Я всегда с собой беру... кусочек кода.

17 46

Наверно у каждого разработчика или толкового администратора всегда есть некий блокнотик, куда вбиты основные и наиболее часто используемые фрагменты кода. Давайте я начну своей статьей и выпишу свои любимые фрагменты, а вы подхватите! Представьте какой у нас получится Шпаргальник!

И сразу к делу!

1. Определение пользователя, группы, роли:

CurrentUser = ServiceFactory.GetUserByName(Application.Connection.UserName) // Текущий пользователь
Admin = ServiceFactory.GetGroupMembers(ServiceFactory.GetGroupByName('Administrators')).Find(CurrentUser) // Группа администраторов
FinDirectorRole = ServiceFactory.GetRoleMembers(ServiceFactory.GetRoleByName('ФинДиректор'); NIL) // Роль Финансового директора
  IsFinDirector = FinDirectorRole.Find(CurrentUser)
// Admin и IsFinDirector соответственно принимают значения TRUE, если пользователь относится к ним

2. Переборка параметров по Именам:

RequisitesTabMain = 'Sourcers;Direction;ProjectStatus;Работник;ДаНет2' // Перечисляем
    foreach ReqName in CSubString(RequisitesTabMain; ';')  // Перебираем
      if Object.Requisites(ReqName).CanGUIWrite   // Проверяем
        Object.Requisites(ReqName).CanGUIWrite = FALSE // Делаем
      endif
    endforeach

3. Начало задачи (Параметры и проверка документа):

Params = Sender.WorkFlowParams
  // Подтянуть вложенный документ в параметры Маршрута
  Attachments = Sender.GetAttachments(True) // Активируем
  foreach Attachment in Attachments // Просматриваем
    EDocInfo = Attachment.ObjectInfo     
    if EDocInfo.ComponentType = ctEDocument // А это точно документ?
      if EDocuments.GetObjectByID(EDocInfo.id).SYSREQ_EDOC_KIND == 'Д000095' // Отбираем основной вид
      Params.ValueByName("Attachment").Value = EDocInfo // Подхватываем в параметры маршрута
    endif
  endforeach

  if not Assigned(Params.ValueByName("Attachment").Value) // Обозначим ошибку без документа!
      Raise(СоздатьИсключение('ВНИМАНИЕ!'; 'Не вложен основной документ!'; ecException))
  endif
// Объявим тему исходящей задачи
  Object.Subject = Format("Согласование: %s";EDocuments.GetObjectByID(EDocInfo.id).SYSREQ_EDOC_NAME)

4. Теперь События Задания (Тема):

Params = Object.WorkFlowParams
EDocInfo = Params.ValueByName("Attachment").Value
Sender.Properties.ValueByName(JOB_BLOCK_SUBJECT_PROPERTY).Value = Format("Согласование: %s"; EDocInfo.Name)

5. Отправка почты с вложениями из задачи:

  TempFolder = GetTempFolder() 
  AttachmentsListStr = ""
  МоментЗапуска = Params.ValueByName("Moment").Value  
  EDocInfo = Params.ValueByName("Attachment").Value
  RassEmail = Params.ValueByName("email2").Value

        // Получить электронный документ   
        EDoc = EDocInfo.Document 
        // Определить номер экспортируемой версии
        VersionNum = GetNumVersionEDoc(EDoc; EDOC_VERSION_ACTIVE_STAGE_CODE)
        if VersionNum = -1
          VersionNum = GetNumVersionEDoc(EDoc; EDOC_VERSION_DESIGN_STAGE_CODE)
          if VersionNum = -1
            VersionNum = GetNumVersionEDoc(EDoc; EDOC_VERSION_OBSOLETE_STAGE_CODE)
          endif
        endif
        // Сформировать наименование фaйла
        EDocumentVersion = EDoc.Versions.ValueByName(VersionNum)
        FileName = GetFullEDocumentVersionFileName(EDocumentVersion; TempFolder)
        // Экспортировать документ во временную папку    
        EDoc.Export(VersionNum; FileName; FALSE)
        // Добавить имя экспортированного файла в список вложений
        AttachmentsListStr = AddSubString(FileName; AttachmentsListStr; ';')    

Theme = 'Новые точки от' & МоментЗапуска
MailText = 'Коллеги, внесены новые точки!' & CR
MailText = MailText & 'Информация во вложении.' & CR & CR & 'Данное сообщение сформировано автоматически, просьба - не отвечать на него!'
//******************************************************************************
ПЧТОтправитьПисьмо(RassEmail;;;Theme;MailText;;AttachmentsListStr;)

6. Наполнение Списка Пользователей в маршруте из справочника:

UserList1 = ServiceFactory.GetUSerList 
UserList2 = ServiceFactory.GetUSerList
UserList3 = ServiceFactory.GetUSerList
КДГDDS = References.КДГ.GetObjectByCode(КатДог) // Получение элемента справочника из документа
// КатДог - реквизит документа типа "Категория договора"
Listering1 = КДГDDS.DetailDataSet(2)
 foreach List in Listering1
    UserList1.Add(ServiceFactory.GetUserByCode(List.Requisites("RabLevel1").Value))
 endforeach
Listering2 = КДГDDS.DetailDataSet(3)
  if Listering2.RecordCount > 0
   foreach List in Listering2 
      UserList2.Add(ServiceFactory.GetUserByCode(List.Requisites("RabLevel_2").Value))
   endforeach 
endif
Listering3 = КДГDDS.DetailDataSet(4)
  if Listering3.RecordCount > 0
    foreach List in Listering3 
      UserList3.Add(ServiceFactory.GetUserByCode(List.Requisites("RabLevel_3").Value))
   endforeach
  endif 
Params.ValueByName("1Уровень").Value = UserList1 // Параметр типа Список пользователей
Params.ValueByName("2Уровень").Value = UserList2 // Параметр типа Список пользователей
Params.ValueByName("3Уровень").Value = UserList3 // Параметр типа Список пользователей

7. Формирование листа согласования и вложения его в документ по окончанию маршрута:

Params = Object.WorkFlowParams

CurrentUser = Object.Requisites("Author").DisplayText     // Получаем Инициатора
USERL = ServiceFactory.GetUserByCode(НайтиРеквизитПоФИО(CurrentUser; "Пользователь"))      
JobIndex = 1       // Индекс

  Задача = Tasks.GetObjectByID(Object.ID)       // Формализуем для работы
  DetailJobs = Задача.DetailDataSet(3)          // Полоучаем Job`ы задачи
  NameP = Задача.SYSREQ_ID                      // Снимаем имя задачи в переменную для Листа согласования
  DetailJobs.Index = ArrayOf('EndDate;ASC'; 'Performer;ASC')    // Сортируем по дате и ФИО
  DetailJobs.Indexed = TRUE  
  DetailText = Задача.DetailDataSet(5)  // Получить детальный раздел "Тексты заданий"
  JobsList = CreateList()               // Создать список заданий
  foreach DetailJob in DetailJobs       // Пока мы получаем Job`ы
    JobID = DetailJob.SYSREQ_ID         // ID Job
    AuthorJob = ServiceFactory.GetUserByCode(DetailJob.Performer).FullName      // Ловим автора Задания
    JobText = ""    // Обозначаем переменную
    if DetailText.Locate("JobID"; JobID)     // Формируем строку с данными для дальнейшей работы
      JobText = JobIndex & "|"& AuthorJob & "|" & DetailJob.UTCModified & "|" & DetailText.Text
    endif
    if JobText <<>> ""      // Заполняем лист, индексируем
      JobsList.Add(JobIndex; JobText)
      JobIndex = JobIndex + 1 
    endif                
  endforeach
   
  Excel = CreateObject("Excel.Application")     // Теперь готовим к работе Excel
  ExcelBook = Excel.Workbooks.Add               // Готовим...
  WorkSheet = ExcelBook.WorkSheets(1)           // Готовим...
  WorkSheet.Activate                            // Готовим...
    WorkSheet.Rows(1).Cells(4).Value = 'Лист Согласования сформирован автоматически:'    
    WorkSheet.Rows(2).Cells(4).Value = "GUID: " & GetHashInFormatGUID(Задача.ID)         
    WorkSheet.Rows(3).Cells(2).Value = "ID: " & Задача.ID                                
    WorkSheet.Rows(4).Cells(2).Value = "ТЕМА: " & Задача.Subject                         
    WorkSheet.Rows(7).Cells(1).Value = '№'                                               
    WorkSheet.Rows(7).Cells(2).Value = 'Исполнитель'                                     
    WorkSheet.Rows(7).Cells(3).Value = 'Когда выполнено'                                 
    WorkSheet.Rows(7).Cells(4).Value = 'Содержание ответа'                               

    index = 8     // Указываем на строку, с которой начинается таблица
    foreach JobText in JobsList     // Снимаем строки и заполняем таблицу по кусочкам:
        WorkSheet.Rows(Index).Cells(1).Value = SubString(JobText;"|";1)
        WorkSheet.Rows(Index).Cells(2).Value = SubString(JobText;"|";2)
        WorkSheet.Rows(Index).Cells(3).Value = SubString(JobText;"|";3)
        WorkSheet.Rows(Index).Cells(4).Value = Trim(SubString(JobText;"|";4))
        Index = Index + 1
    endforeach    
    WorkSheet.Rows(Index + 1).Cells(2).Value = "Инициатор задачи: " & CurrentUser  
    WorkSheet.Rows(Index + 2).Cells(2).Value = Сейчас()  
      
// Наводим красоту с жестким фанатизмом. Как и где найти мануал - отвечаю: https://club.directum.ru/post/773
  Подпись1 = Index + 1
  Подпись2 = Index + 2 
  Край = Index - 1
  
  WorkSheet.Range("B4:D5").Merge
  WorkSheet.Range("B4").WrapText = True
  WorkSheet.Range("D:D").WrapText = True
  WorkSheet.Range("D1").Font.Underline = True
  WorkSheet.Range("D1").Font.Italic = True
  WorkSheet.Range("D2").Font.Underline = True
  WorkSheet.Range("D2").Font.Italic = True
  WorkSheet.Range("D2").Font.Size = 9
  WorkSheet.Rows("6:30").EntireRow.AutoFit
  WorkSheet.Range("B3:B5").Font.Bold = True
         
  WorkSheet.Columns("A:A").ColumnWidth = 2  //EntireColumn.AutoFit
  WorkSheet.Columns("B:B").ColumnWidth = 35 //EntireColumn.AutoFit
  WorkSheet.Columns("C:C").ColumnWidth = 20 //EntireColumn.AutoFit
  WorkSheet.Columns("D:D").ColumnWidth = 60 //EntireColumn.AutoFit
  WorkSheet.Range("B" & Подпись1 & ":B" & Подпись2).Font.Bold = True
  WorkSheet.Range("B" & Подпись1 & ":B" & Подпись2).HorizontalAlignment = -4131
  WorkSheet.Range("B" & Подпись1 & ":B" & Подпись2).VerticalAlignment = -4108
  WorkSheet.Range("A1:D" & Край).HorizontalAlignment = -4131                   
  WorkSheet.Range("A1:D" & Край).VerticalAlignment = -4108
  WorkSheet.Range("A7:D" & Край).Borders(7).LineStyle = 1
  WorkSheet.Range("A7:D" & Край).Borders(8).LineStyle = 1
  WorkSheet.Range("A7:D" & Край).Borders(9).LineStyle = 1
  WorkSheet.Range("A7:D" & Край).Borders(10).LineStyle = 1
  WorkSheet.Range("A7:D" & Край).Borders(11).LineStyle = 1
  WorkSheet.Range("A7:D" & Край).Borders(12).LineStyle = 1
  WorkSheet.Range("D1").HorizontalAlignment = -4152
  WorkSheet.Range("D2").HorizontalAlignment = -4152
  WorkSheet.Range("A7:D7").HorizontalAlignment = -4108
  WorkSheet.Range("A7:D7").Font.Bold = True
  WorkSheet.PageSetup.Orientation = 2

//Сохраняем Нашу таблицу в PDF и XLS
  FilenamePDF = 'C:\Temp\Лист_Согласования_' & Задача.ID & ".pdf"  
  FilenameXLS = "C:\Temp\Temporary.xls"   
  ExcelBook.SaveAs(FilenameXLS)  // Сохраняем таблицу в XLS, этого можно и не делать, но так происходит работе без лишних вопросов   
  ExcelBook.ExportAsFixedFormat(0; FilenamePDF;1; FALSE; FALSE) // Сохраняем таблицу в PDF
  Excel.Quit                // Закрываем Excel без вопросов
  ExcelBook = nil           // Убираемся
  Excel = nil               // Убираемся                           
  УдалитьФайл(FilenameXLS)  // Убираемся, так как работа с таблицей закончена
       
   Attachments = Object.GetAttachments(True)
   DocSog = EDocuments.CreateNewFromFile('ПЭА'; 'Д000055'; 'ACROREAD'; FilenamePDF)
   try
     SetAccessRightsEDoc(DocSog.Info; ; ; USERL)  
   except
     //  
   endexcept   
   Attachments.Add(DocSog.Info)
   DocSog.Save   
  Object.Save
  EDocInfo = nil 
  УдалитьФайл(FilenamePDF)  

8. Старт задачи из другой задачи при помощи кода:

Task = Tasks.CreateNew()
Task.LoadStandardRoute('CancelS')
Task.Subject = Format("Внимание! Инициирована отмена! Клиент: %s | Менеджер: %s"; ArrayOf(Клиент; ServiceFactory.GetUserByName(Params.ValueByName('OsnManager').Value).FullName)) 
Task.get
Task.Author = 'Д005669' // Автор указывается конкретно
TaskParms = Task.WorkflowParams
TaskParms.ValueByName('OsnManager').Value = Params.ValueByName('OsnManager').Value
TaskParms.ValueByName('Клиент').Value = Клиент 
TaskParms.ValueByName('Отказ').Value = Params.ValueByName('Отказ').Value
if Assigned(Params.ValueByName('Отказ2').Value)
  TaskParms.ValueByName('Отказ2').Value = Params.ValueByName('Отказ2').Value
endif
if Assigned(Params.ValueByName('Отказ3').Value)
  TaskParms.ValueByName('Отказ3').Value = Params.ValueByName('Отказ3').Value
endif 

  ActText = 'Ведущий Менеджер: ' & ServiceFactory.GetUserByName(Params.ValueByName('OsnManager').Value).FullName & CR &  
  'Наименование клиента: ' & Params.ValueByName('Клиент').Value & CR & 
  'Вид Деятельности клиента: ' & Params.ValueByName('ВидДеятельности').Value & CR & 
  'Торговое наименование: ' & Params.ValueByName('ТорговоеНаименование').Value & CR & 
  'ИНН: ' & Params.ValueByName('ИНН').Value & CR
  if Assigned(Params.ValueByName('email').Value)  
      ActText = ActText & 'E-mail клиента: ' & Params.ValueByName('email').Value & CR
  endif
  if Assigned(Params.ValueByName('Контакты').Value)
      ActText = ActText & 'Контактный телефон: ' & Params.ValueByName('Контакты').Value & CR
  endif
  ActText = ActText & '========================================================='
TaskParms.ValueByName('ActText').Value = ActText

Task.Start()

9.  Нарезка того, что частенько требуется в работе:

Ref = CreateReference('РАБ') // Указываем справочник
// или так: References.РАБ.GetComponent()
AddWhere = Ref.AddWhere(Format("%s.%s = 'З'"; ArrayOf(Ref.TableName; Ref.Requisites('Состояние').SQLFieldName)))
    View = Ref.CreateView('Главное')                     
    View.ViewMode =  vmSelect 
    View.MultiSelection = TRUE
    View.MainForm.Show

Ref.DelWhere(AddWhere) 
//**********************************************************
//РАСШИРЕНИЕ ДОКУМЕНТА:
Docum = EDocuments.GetObjectByID(Doc.ID) 
Docum.Info.Editor.Extension 
//**********************************************************
// Генерация из шаблона:
EDoc = EDocuments.CreateNewFromTemplate('TMCards';'Д000091';'Д004330')
ФИО = Params.ValueByName("ФИО").Value
EDoc.Requisites('ISBEDocName').Value = "Служебная записка на прием на работу Кандидата: "& ФИО & " от " & Today() 
EDoc.Save()
ТМДобавитьВложение("Эл.документ";EDoc.ID)
//**********************************************************
// Вычислить работника и его руководителя:
Params.ValueByName("Инициатор").Value = ServiceFactory.GetUserByCode(Object.Author)
  Работник =  EDocuments.GetObjectByID(EDocInfo.id).Requisites('Персона').DisplayText
  КодПользователя = НайтиРеквизитПоФИО(Работник; 'Пользователь')
  Руководитель = ServiceFactory.GetUserByCode(КодПользователя)
//**********************************************************
// Показать связанные эл. документы      
  GetBoundEDocuments(Object; EDocKind; TRUE; ReadOnly; RightsToRead; RightsToWrite)
//**********************************************************
// Excel:
ExcelApp = CreateObject("Excel.Application")
NewWb = ExcelApp.WorkBooks.Add
Sh = NewWb.Sheets(1)
Astr = 1
Sh.Range("D" & Astr).Value = Данные
Sh.Columns("A:A").ColumnWidth = 50
Sh.Rows("1:1").RowHeight = 25
Sh.Range("A1:E1").Select
Selection = ExcelApp.Selection
Selection.Font.Bold = True
xlcenter = -4108				// По центру
Selection.HorizontalAlignment = xlcenter
Selection.VerticalAlignment = xlcenter
Sh.Range("A1:E1").Select
    Selection.AutoFilter
Sh.Range("A1").Select
NewWb.SaveAs("C:\temp\PS.xlsx")
ExcelApp.WorkBooks.Close
//**********************************************************
// Сбор данных из наименования справочника:
Список = CreateStringList()
Список.Delimiter = ';'
foreach Sprkod in CSubString(ПоискСпр('АДР';'Состояние:Действующая'); '|')
      Список.Add(ReferenceRequisiteValue('АДР';Sprkod;'Строка'))  
endforeach
RassEmail = Список.DelimitedText 
//**********************************************************
// Сам себе руководитель:
if ServiceFactory.GetUserByCode(Object.Author) == Руководитель // Руководитель - параметр
      Params.ValueByName('РуководительКандидата').Value = ServiceFactory.GetUserByCode(Object.Author)
  else
      Params.ValueByName('РуководительКандидата').Value = Руководитель
  endif
//**********************************************************
// Планировщик заданий:
//"C:\Program Files (x86)\Common Files\NPO Computer Shared\IS-Builder\SAJobRunner.exe"
//-S="ServerDir" -D="DIRECTUM" -CT="Script" -F="ScriptName"

В моем блокнотике пока это наиболее популярная подборка. А что есть у вас? Делимся - не стесняемся! 

Фёдор Сироткин

Тарас, сегодня в ударе. Статья на статьёй. 

Тоже собираюсь сделать такую копилку. Но пока не много.

Отобразить критерии поиска для механизма поисков:

Search = Searches.CreateNew(ckEDocument) 
Criteries = Search.SearchCriteria
T = 'Критерии поиска:' 
ForEach RequisiteDescription in Search.RequisiteDescriptionList 
   T = AddSubString(RequisiteDescription.Name & TAB & RequisiteDescription.Title; T; CR)  
EndForEach 
EditText(T)
Criteries.Add('КритерийПоиска').Add(Object.SYSREQ_CODE)
Searches.Show(Search)

Число элементов в массиве и перебор элементов:

Array = ArrayOf('v1'; 'v2'; 'v3')
CArray = CArrayElement(Array)
Count = CArray.Count
ForEach Element In CArray
  ShowMessage(Element)
EndForEach

Реверс списка:

List = CreateList()
List.Add(3; 'Значение 1')
List.Add(5; 'Значение 2')
List.Add(1; 'Значение 3')
ForEach Item In List
  ShowMessage(Item)
EndForEach
// В обратном порядке
i = List.Count - 1
While i >= 0
  ShowMessage(List.Names(i))
  ShowMessage(List.Values(i))
i = i - 1
EndWhile

 

Сергей Меньших
CurrentUser = ServiceFactory.GetUserByName(Application.Connection.UserName) // Текущий пользователь

есть немного проще вариант

CurrentUser = EDocuments.CurrentUser

 

FinDirectorRole = ServiceFactory.GetRoleMembers(ServiceFactory.GetRoleByName('ФинДиректор'); NIL) // Роль Финансового директора

тут главное не забывать в этой шпаргалке, что это только для стат. роли, для вычисляемой надо Sender передавать =)

Task.Start()

Я не использую такой вызов без Try ... Exception. Задачка ведь может и не создаться.

Даниил Бабарин

В качестве базы удобных инструментариев, не могу не отметить когда-то найденную здесь библиотеку функций UDL.. Очень много полезного кода было выцеплено оттуда. Уж не знаю кому сказать спасибо, но пригодилась она здорово..

*. Если пользуюсь МД, то собираю в окно результатов все выбранные пользователем значения, разместив их в скрытом листе и отображая в спец. этапе..

If not _Assigned(Wizard)
  Raise(CreateException('';'Не передан объект - МД, в переменной Wizard';ecWarning))    
EndIf

If not _Assigned(StepName)
  Raise(CreateException('';'Не передано имя этапа для сканирования в переменной StepName';ecWarning))    
EndIf


// Получить все элементы формы этапа 
Try
  Elements = Wizard.Steps.ValueByName('Скрытый. Лист результата').Elements
Except
  Raise(CreateException('';Format('Нет такого этапа «%s» в переданном МД «».';ArrayOf(StepName;Wizard.Name));ecWarning))
EndExcept
  // Перебираем его элементы
foreach Element in Elements
  // Если элемент формы связан с параметром
  if Element.ElementType = wfetQueryParameter
    // Получить параметр
    Param = Element.Parameter
    // Для разных типаов параметров формировать значение по-разному
    // Для параметров типа Запись справочника брать Наименование
    if in(ArrayOf(wptReferenceRecordInfo; wptUser); Param.ParamType)
      ParamValue = ''
      if Assigned(Param.Value)
        if Param.ParamType = wptUser
          ParamValue = Param.Value.FullName
        else
          ParamValue = Param.Value.Name
        endif
      endif
    else
      // Для параметров типа Список записей справочников сформировать нумерованный список
      if in(ArrayOf(wptReferenceRecordInfoList; wptUserList; wptEDocumentInfoList); Param.ParamType) 
        ParamValue = ''
        if Assigned(Param.Value)
          ParamValue = TAB
          foreach Record in Param.Value
            if Param.ParamType = wptUserList
              ParamValue = AddSubString(Format('%s%s'; ArrayOf(TAB & TAB; Record.FullName)); ParamValue; CR)
            else
              ParamValue = AddSubString(Format('%s%s'; ArrayOf(TAB & TAB; Record.Name)); ParamValue; CR)
            endif
          endforeach
        endif 
      else
        // Для всех остальных типов параметров взять просто значение
        ParamValue = Param.Value  
      endif         
    endif
    ParamValue = Format('%s%s: %s'; ArrayOf(TAB; Param.Title; ParamValue))
    Result = AddSubString(ParamValue; Result; CR)
  endif    
endforeach

*. Часто пользуюсь заполняемым реквизитом типа признак в диалогах, динамически высчитываю ID очередной записи. Ф-я "_GetNextSymvInCount"

If not Assigned(CurrentValueOfCount)
  Raise(CreateException('';'Не передано значение параметра CurrentValueOfCount';ecWarning))    
endif

  // До 10 можем вернуть текущее значение счётчика, это ОК, т.к. цифра однозначная (а не двузначная и больше)
If CurrentValueOfCount < 10
  Result = CurrentValueOfCount
Else
  // Будем возвращать буквы англ. алфавита. Их 26. Сперва вернём заглавные буквы, потом прописные
    // Заглавные
  If CurrentValueOfCount >=10 and CurrentValueOfCount <=36
      // Буква "A" имеет код 65. "Z" - код 90.
    CurrentValueOfCount = 55+CurrentValueOfCount
      // Получаем символ по коду
    Result = Char(CurrentValueOfCount)
    
    // Прописные
  else if CurrentValueOfCount >= 37 and CurrentValueOfCount <=63
  
      // Буква "a" имеет код 97. "Z" - код 122.
    CurrentValueOfCount = 60+CurrentValueOfCount
      // Получаем символ по коду
    Result = Char(CurrentValueOfCount)
  
  else
    Raise(CreateException('';'Слишком большое значение счетчика, нет сопоставимых букв';ecWarning))
  Endif Endif
EndIf

Само заполнение реквизита

i = 1
while ...
Object.Requisites("ChooseUser").Items.Add(_GetNextSymvInCount(i); Record.SYSREQ_CODE; Record.SYSREQ_NAME)
i = i + 1
endwhile
// включая выставить значением по умолчанию первое значение списка
Object.Requisites("ChooseUser").Value = Object.Requisites("ChooseUser").Items.Value.Value

* Иногда приходилось дебажить таблицы с скрытыми реквизитами, отображает все записи и все реквизиты и их значения переданной DDS

  // Таблица данных, основная или дополнительная, которую будем сканировать
If not Assigned(DataSet)
  Raise(CreateException('EDIRInvalidUserAction'; LoadStringFmt('DIR82CF5DAD_AD28_4B83_9B21_D3561FE30F62'; 'COMMON'; 'DataSet'); ecWarning))
EndIf

  // Список строк, в который будем записывать информацию о реквизитах
RequisiteList= CreateStringList()
  // Разделитель между строками – знак переноса строки, CR
RequisiteList.Delimiter = CR

RequisiteList.Add('Количество записей: «'& DataSet.RecordCount &'»')
RequisiteList.Add('Количество реквизитов: «'& DataSet.RequisiteCount &'»')
RequisiteList.Add(' ')
  // Пройдёмся по каждой записи
ForEach Record in DataSet
  ReqIndex = 0
  RequisiteList.Add('Запись номер: «'& Record.SYSREQ_LINE_NUMBER &'»')  
    // Пройдемся по всем реквизитам текущей записи
  while ReqIndex < DataSet.RequisiteCount
    Record = DataSet.RequisiteByIndex(ReqIndex) 
    RequisiteList.Add('Req Name          - «'& Record.Name &'»')
    RequisiteList.Add('Req Field Name    - «'& Record.SQLFieldName &'»')  
    RequisiteList.Add('Req SQLField Name - «'& Record.FieldName &'»')
    If Record.DataType == rdtText
      RequisiteList.Add('Req Value is text, skipping')
    Else
      RequisiteList.Add('Req Value         - «'& Record.AsString &'»')
    EndIf
    RequisiteList.Add("----------") 
    ReqIndex = ReqIndex + 1
  endwhile
RequisiteList.Add('=======================================')
RequisiteList.Add(' ')    
EndForEach  
EditText(RequisiteList.DelimitedText)      


* Полезная и малоиспользуемая фича - объявление переменной сразу в разрезе определенной ТКЭД. Вспоминаю только когда смотрю в блокнот, никак не привыкну 

EDoc : IEDocument.TFD_DCTS_EML = 

* Всякие формы для проверки реквизитов вовсе записал в конструкции редатора кода ISBL и теперь быстро вызываю, например, оформление "красивых" стен аля

/*------------------------------------------------------------------------------
                    
------------------------------------------------------------------------------*/

//----------------------------------------------------------------------------//

Или, например самое частоиспользуемое в функциях и сценариях, такая обертка

If not Assigned(XXX)
  Raise(CreateException('EDIRInvalidUserAction'; LoadStringFmt('DIR82CF5DAD_AD28_4B83_9B21_D3561FE30F62'; 'COMMON'; 'XXX'); ecWarning))     
EndIf   

 

Алексей Семакин

Копилка — это полезно. Объединить копилки — двойная польза. Но сваливать их в кучу в комментариях, наверное, не самый классный способ организации знаний. Смотрите, у нас есть база знаний, есть "Вопросы", есть даже примеры кода в справке. Как считаете, есть ли у какого-то из этих инструментов перспектива превратиться в удобную базу сниппетов для решения типовых задач? Какого функционала от такой базы ожидаете вы? Чего не хватает сейчас? Почему до сих пор в блокнотиках? :)

Мои 5 копеек — список ИД групп пользователей, подчиненных группе "Developers" и просто "рыба" для написания рекурсивных запросов:

PIPELINE = "|"
InitialGroupName = "Developers"
Query = Format("with GroupTree (GroupID) as
                (
                  select  UserID
                  from    MBUser
                  where   UserKod = '%s'
                          and UserType = 'Г'
                  
                  union all
                  
                  select  Groups.UserID
                  from    MBUser Groups
                          join GroupTree on GroupTree.GroupID = Groups.ParentGroup
                  where   Groups.ParentGroup is not null
                  
                )
                
                select * from GroupTree
                option (maxrecursion 32)"; InitialGroupName)
RMGroupTree = SQL(Query; ; PIPELINE)

 

 

Сергей Меньших

Поделюсь и я чем-нибудь

// Регулярные выражения
ValueString = 'ФИО - Петрович Л Л
Дата приёма - 15.03.2019
Должность - тест
Подразделение - тест
Организация - тест
Инв. номер оборудования - тест
Тел. номер - 
Доп. информация - 
Контактное лицо - Разуваева Мария Валерьевна'
RegExp = CreateObject('VBScript.RegExp')
RegExp.Global = TRUE 
RegExp.IgnoreCase = TRUE
RegExp.Multiline = TRUE        
RegExp.Pattern = "(.*)\s\-\s(.*)"
Matches = RegExp.Execute(ValueString)
i = 0
while i < Matches.Count
  Match = Matches.Item(i).Value
  ShowMessage(Match)  
  Submatches = Matches.Item(i).Submatches
  Submatch0 = Submatches.Item(0)
  Submatch1 = Submatches.Item(1)
  ShowMessage(Submatch1)
  i = i + 1 
endwhile



// Формирование документа PDF из документа Excel при помощи VBAScript
PathFilelExcel = "C:\test\test.xlsx"
PathFilelPDF = "C:\test\test.pdf" 
ScriptControl = CreateObject("MSScriptControl.ScriptControl")
ScriptControl.Language = "VBScript"
ScriptControl.Reset
Script = '  
  On Error Resume Next
    Set objExcel = GetObject(, "Excel.Application")
  If objExcel Is Nothing Then Set objExcel = CreateObject("Excel.Application")
  On Error GoTo 0  
    
  Set objWorkbooks = objExcel.Workbooks.Open("%0:s")
  Set objWorksheets = objWorkbooks.Worksheets(1)
  objExcel.DisplayAlerts = False
  objWorkbooks.SaveAs "%1:s", 57
  objWorkbooks.Close
  Set objWorkbooks = Nothing
  Set objWorksheets = Nothing
  Set objExcel = Nothing
  '
Script = Format(Script; ArrayOf(
  PathFilelExcel;
  PathFilelPDF
))
ScriptControl.ExecuteStatement(Script)



// Формирование документа PDF из документа Excel при помощи DCOM 
PathFilelExcel = "C:\test\test.xlsx"
PathFilelPDF = "C:\test\test.pdf"
FormatType = 0 // формат документа - PDF
FormatQuality = 1 // качество экспортируемого файла 
IncludeDocProperties = true
IgnorePrintAreas = true
Excel = CreateObject('Excel.Application')
Book = Excel.Workbooks.Open(PathFilelExcel)
Sheets = Book.Sheets(1)
Sheets.ExportAsFixedFormat(FormatType; PathFilelPDF; FormatQuality; IncludeDocProperties; IgnorePrintAreas)
Book.Close()
Excel.Quit()



// Выбор пользователей с моментальным открытием справочника
Result = CreateInputDialog('Пользователи'; ''; 'ReferenceM:ПОЛ';'Параметры типового маршрута';;;;;'User')
Result.Form.ShowNoModal                   
Result.Form.Actions.FindAction('LookupAction').Execute

 

Сергей Меньших

Немного полезных функций для работы с пользователями

        LD_AddUserListToUserList
        LD_ConvertStringListToUsers
        LD_ConvertUsersToStringList
        LD_UserListAddUser
        LD_UserListDeleteUser
        LD_UserListMerge

Прикреплен файл: func_users.zip

Сергей Меньших: обновлено 22.08.2019 в 15:23
Артем Сунцов

Копилка - штука полезная. Тем, кто будет использовать рекомендации Тараса, крайне рекомендую в п.3 вместо вызова исключения при отсутствии нужного документа ставить признак обязательной запрашиваемости у соответствующего параметра; а соответствие вида/типа проверять уже после запроса параметров. Текущий метод из п.3 кастрирует доступные способы инициирования задач по ТМ.

Свою копилку не собирал, но несколько примеров докину:

При разработке типов справочников, событие Сохранение возможность:

 // Не давать сохранять не утвержденные записи
  if Object.Requisites(SYSREQ_RECORD_STATUS).AsString == "?"
    // Должны быть заполнены все обязательные реквизиты
    Message = LoadString('DIRF1E053C9_B6E2_4F21_B056_B00E7F4D435D'; 'DISI')
    Raise(CreateException('EDIRInvalidRequisiteValue'; Message; ecWarning))
  endif

Переопределение выбора записи справочника на пользовательский, на примере Работников:

  ADD_WHERE_VARIABLE_NAME = "AddWhereCondition"
  REQUISITE_DEPARTMENT = "Подразделение"
  
  // Добавить в фильтр условие, что у работника указан пользователь и работник действующий
  EmplRef = CreateReference('РАБ')
  UserRef = CreateReference('ПОЛ')
  AddWhere = Format("%0:s.%1:s = 'Д' AND %0:s.%2:s IN (SELECT usr.%3:s FROM %4:s usr WHERE %0:s.%2:s = usr.%3:s AND usr.%5:s = 'Д')"; ArrayOf(
    EmplRef.SQLTableName; EmplRef.Requisites(SYSREQ_STATE).SQLFieldName;
    EmplRef.Requisites('Пользователь').SQLFieldName;
    UserRef.Requisites(SYSREQ_ID).SQLFieldName; UserRef.SQLTableName;
    UserRef.Requisites(SYSREQ_STATE).SQLFieldName
  ))
  Object.Environment.SetVar(ADD_WHERE_VARIABLE_NAME; AddWhere)
  
  SelectFromReferenceAction('РАБ'; SelectMode; InputValue; Requisite;)
  
  if Object.Environment.IndexOfName(ADD_WHERE_VARIABLE_NAME) >= 0
    Object.Environment.PopVar(ADD_WHERE_VARIABLE_NAME)
  endif
  
  EmplRef = nil
  UserRef = nil

Проверка вхождения текущего пользователя или замещаемых им пользователей в группы (в основном, используется в более сложных условиях для оптимизации скорости ограничения набора данных справочников или доступных реквизитов, но полезно и просто для нормального отображения содержимого справочника с учётом имеющихся замещений):

  UserName = Application.Connection.UserName
  User = ServiceFactory.GetUserByName(UserName)
  UserID = User.ID
  GroupRefID = ИДТипСпр('ГПЛ')
  
  // Проверить вхождение пользователя или замещаемого в группы пользователей
  Query = "
          DECLARE
          @UserID int;
          SET @UserID = " & UserID & "
          SELECT 1 WHERE
          EXISTS(SELECT RightsAs.UserID
          FROM dbo.SBFullAccessRights RightsAs
          INNER JOIN dbo.MBAnValR UserGroupsT ON (UserGroupsT.Vid = " & GroupRefID & " AND UserGroupsT.PolzovatelT = RightsAs.UserOrGroupID)
          INNER JOIN dbo.MBAnalit UserGroups ON (UserGroupsT.Analit = UserGroups.Analit AND UserGroups.Dop IN ('<имя группы 1>','<имя группы 2>',...))
          WHERE RightsAs.UserID = @UserID)"
  MemberOfGroups = Assigned(SQL(Query))

 

Артем Сунцов

Алексей Семакин, считаю что полезным будет ввести контекстно-зависимые шаблоны (развить текущий функционал, позволяющий быстро вставлять конструкции try .. except, ...)

Алексей Семакин

Артем, механизм контекстно зависимых шаблонов не закрыт — туда можно добавлять свои шаблоны. Если там не достает какого-то полезного функционала, то смело оформляйте идею.

Но база сниппетов — это другое. На мой взгляд, это общедоступная база готовых примеров кода для решения  задач, не обязательно часто встречающихся. Причем для одной и той же задачи сниппетов может быть несколько (один — быстрый, другой — красивый  ). Предложить свой сниппет в базу может любой ее пользователь, и его сниппет после модерации, сразу доступен всем. Модерация нужна — кто-то должен следить за тем, чтобы сниппеты, как минимум, удобно и единообразно искались, чтобы не было совсем уж дублирующихся. Сниппеты должны находиться как поисковым запросом по фрагменту сниппета, так и по тегам. Кроме того, нужна возможность просто серфить по базе — когда поиск нужных результатов не дал, я захочу пройти сам по дереву сниппетов и найти что-то близкое к моей задаче. По какому принципу строить дерево, и дерево ли — отдельный вопрос.

Алексей Семакин: обновлено 30.08.2019 в 17:45
Тарас Асачёв

Сценарий по удалению пользователей из группы:

Group = References.ГПЛ.GetComponent
AddwhereGroup = Group.AddWhere(Format("%s.%s = 'Д'"; ArrayOf(Group.TableName; Group.Requisites('Состояние').SQLFieldName)))
  View = Group.CreateView('Главное')
  View.ViewMode =  vmSelect 
  View.MultiSelection = FALSE
  View.MainForm.Show
  if View.MainForm.Result = mrOK
    GroupName = References.SYSREF_USER_GROUPS_REFERENCE.GetObjectByID(View.SelectedRecordsID(0))
  else
    exit()
  endif
Userlist = ''
DDSGROUP = GroupName.DetailDataSet(1)
DDSGROUP.OpenRecord
foreach gpol in DDSGROUP
  Userlist = AddSubString(ServiceFactory.GetUserByCode(gpol.Requisites("ПользовательТ").Value).ID; Userlist; ',') 
endforeach   
Ref = CreateReference('ПОЛ')       // Указываем справочник 
Addwhere = Ref.AddWhere(Format("%s.%s in (%s)"; ArrayOf(Ref.TableName; Ref.Requisites('ИД').SQLFieldName; Userlist)))
  View = Ref.CreateView('Главное')
  View.ViewMode =  vmSelect 
  View.MultiSelection = TRUE
  ShowMessage('Выберите пользователей на удаление!')
  View.MainForm.Show
  index = 0
  if View.MainForm.Result = mrOK
    FinalText = Сейчас() & CR
    while index < View.SelectedRecordCount
      IDUser = View.SelectedRecordsID(index)
      foreach gpol in DDSGROUP
        if IDUser == ServiceFactory.GetUserByCode(gpol.Requisites("ПользовательТ").Value).ID 
           gpol.Delete
           FinalText = FinalText & 'Из группы "' & GroupName.SYSREQ_NAME & '" Удален пользователь: ' & ServiceFactory.GetUserByID(IDUser).FullName & CR 
        endif 
      endforeach     
      index = index + 1
    endwhile    
    GroupName.Save
    DDSGROUP.CloseRecord
    FinalText = FinalText & Сейчас()
    EditText(FinalText)  
  endif

 

Тарас Асачёв

Предпросмотр в карточке справочника:

Doc = Object.Requisites("Doc").Value
EDoc = EDocuments.GetObjectByID(Doc)
DocVersion = _LastVersionDoc(EDoc)
Rassh = EDoc.Info.Editor.Extension
FileName = GetTempFolder() & 'TmpDoc.' & rassh
EDoc.Export(DocVersion;FileName;FALSE)
WebBrowserControl = Object.Form.Controls.FindControl('STWebBrowserControl1')
if not VarIsNull(WebBrowserControl) 
  WebBrowserControl.Navigate(FileName)        
endif

Есть свои ограничения, но в целом это и к отчету можно прикрутить или сделать вычисления на заполнения HTML документа. 

Тарас Асачёв
Spravochnik = References.Spravochnik.GetComponent
MSG = ''
try
  ind = 0
  while ind < 1000
    PR = Spravochnik.RequisiteByIndex(ind)    
//TReqDataType = (
// тип данных «Строка» = 0,
// тип данных «Дробное число» = 1,
// тип данных «Целое число» = 2,
// тип данных «Дата» = 3,
// тип данных «Справочник» = 4,
// тип данных «Текст» = 6,
// тип данных «Признак»; = 7,
// неизвестный тип данных = 8,
// тип данных «Большое целое число» = 9
// тип данных «Документ» = 10);
    MSG = AddSubString(PR.Name & ' | ' & PR.Title & ' | ' & PR.DataType ;MSG;CR)
    ind = ind + 1  
  endwhile
except
  EditText(MSG)
endexcept

 

Алексей Семакин

Тарас, если я правильно понял, то:
1) try..except понадобился для того, чтобы не свалиться, когда ind перевалит за фактическое количество реквизитов справочника? Чтобы не гадать, лучше вычислить количество реквизитов и ограничить цикл им: IReference.RequisiteCount.

2) ваш "кусочек кода" никак не прокомментирован, и я могу лишь догадываться, что это — получение метаданных о реквизитах главного раздела справочника. Если так, то все это можно выудить одним запросом прямиком из MBVidAnRecv + MBRecvAn. Кажется, там даже кода раза в два меньше получится, и даже цикл не нужен. Собственно вы оттуда же получаете данные, только через объектную модель.

Тарас Асачёв

Алексей, Все верно - решение написанное на коленке, но рабочее и универсальное. А Ваш комментарий очень пригодится) Это же чисто информативное решение чтобы не пользоваться подсказками и поиском реквизитов - не более. 

Тарас Асачёв: обновлено 01.06.2020 в 16:46
Тарас Асачёв

В помощь аудитору: Реестр просрочек по маршрутам за период.

Может это конечно не идеально и много чего надо доработать, но работает!

TMID = ''
Control = Now()
INPTD = InputDialog('ТМ|*Старт с|*Старт по|Формат';
'РСпит|'&НачМес(;Today())&'|'&Today()&'|Только выполненные';'Аналитика:ТМТ|Date|Date|Признак:Только выполненные,Только завершенные,Все';;;;'')
ТМТ     = SubString(INPTD;'|';1)
StartS  = SubString(INPTD;'|';2)
StartPo = SubString(INPTD;'|';3)
BB      = SubString(INPTD;'|';4) 
 TaskSearch = Searches.CreateNew(ckTask)  
 StandarsRouteCode = ТМТ 
 ТМТName = References.ТМТ.GetObjectByCode(ТМТ).SYSREQ_NAME 
 SearchCriteria1 = TaskSearch.SearchCriteria.Add("StandardRoute")
 SearchCriteria1.SetSimpleValue(StandarsRouteCode)
 SearchCriteria2 = TaskSearch.SearchCriteria.Add("TaskState") 
 SearchCriteria2.ValuesBuildType = btOr  
 SearchCriteria2.Add("В работе")
 SearchCriteria2.Add("Выполнена")
 SearchCriteria3 = TaskSearch.SearchCriteria.Add("StartDate")
 SearchCriteria3.AddRange(StartS;StartPo)  
 ContentsTasksInfo = Searches.Execute(TaskSearch) 
 foreach str in ContentsTasksInfo
  TMID = AddSubString(str.ID;TMID;',')
 endforeach
Query = Format(" 
FROM SBTaskJob SBTaskJob
left join [SBTaskProtocol] on [SBTaskProtocol].JobID = SBTaskJob.XRecID
WHERE
SBTaskJob.TaskID in (%0:s)
and SBTaskJob.Kind = 'J' " &
IfThen(BB <<>> 'Все';"and SBTaskJob.EndDate is not NULL ";"") &
IfThen(BB == 'Только выполненные';" and (SBTaskJob.State = 'D')";IfThen(BB == 'Только завершенные';" and ((SBTaskJob.State = 'D') or (SBTaskJob.State = 'B'))";"")) & 
IfThen(BB <<>> 'Все';" and SBTaskJob.EndDate > SBTaskJob.FinalDate";"and GETDATE() > SBTaskJob.FinalDate"); ArrayOf(TMID))
JobsInfos = SQL("SELECT JobID
, Executor
, cast(EndDate as datetime)
, cast(FinalDate as datetime)
, SBTaskJob.TaskID
, State" & Query)
COUNT = SQL("SELECT COUNT(JobID) " & Query)
 Progress = CreateProgress('Выполняется формирование реестра из ' & COUNT & ' записей...';COUNT;TRUE)
 Progress.Show
Resultat = ''
foreach Jinfo in CSubString(JobsInfos;'|')
  Progress.Text = Progress.Position & '. ' & Jobs.GetObjectByID(SubString(Jinfo;';';1)).Name
  JobID       = SubString(Jinfo;';';1)
  Executor    = SubString(Jinfo;';';2)
  MainTaskID  = SubString(Jinfo;';';5)
  State       = IfThen(SubString(Jinfo;';';6)=='B';'Прекращено';IfThen(SubString(Jinfo;';';6)=='D';'Выполнено';'В работе'))
  User = ServiceFactory.GetUserByID(Executor).FullName
  ED = SubString(SubString(Jinfo;';';3);' ';1)
  ET = SubString(SubString(Jinfo;';';3);' ';2)
  if not Assigned(ED)
    ED = SubString(Control;' ';1)
    ET = SubString(Control;' ';2)
  endif
  EndDate = SubString(ED;'-';1) & ' ' & ET 
  FD = SubString(SubString(Jinfo;';';4);' ';1)
  FT = SubString(SubString(Jinfo;';';4);' ';2) 
  FinalDate = SubString(FD;'-';1) & ' ' & FT
  if (РазнВремя('М';FT;ET) - (РазнВремя('Ч';FT;ET) * 60)) > 0
    RCHMIN = РазнВремя('Ч';FT;ET) & ' часов ' & (РазнВремя('М';FT;ET) - (РазнВремя('Ч';FT;ET) * 60))
  else
    RCHMIN = РазнВремя('Ч';FT;ET) & ' часов ' & ((РазнВремя('Ч';FT;ET) * 60) - РазнВремя('М';FT;ET))
  endif 
  //Resultat = AddSubString('Задача: '& MainTaskID & '| Задание ' & JobID & ' выполнил ' & User & ' ' & EndDate & ' при конечном сроке ' & FinalDate & CR & 
  //'Время просрочки: ' & РазнДат('Д';EndDate;FinalDate) & ' дней и ' & RCHMIN & ' минут.';Resultat;CR)
  DataStr = MainTaskID & '|' & JobID & '|' & User & '|' & IfThen(EndDate == Control;'в работе';EndDate) & '|' & FinalDate & '|' & State & 
  '|' & РазнДат('Д';EndDate;FinalDate) & ' дней и ' & RCHMIN & ' минут.'
  if FindSubString(DataStr;Resultat;CR) = 0
    Resultat = AddSubString(DataStr;Resultat;CR)
  endif
  Progress.Next
endforeach
  Progress.Position = 0
  Progress.Title = 'Формируем отчет в MS Excel'
  Progress.Text = 'Ожидайте, осталось недолго...'
  Excel = CreateObject("Excel.Application")   
  ExcelBook = Excel.Workbooks.Add              
  WorkSheet = ExcelBook.WorkSheets(1)         
  WorkSheet.Activate                          
    WorkSheet.Rows(1).Cells(1).Value = 'Реестр просроченных заданий по маршруту "'&ТМТName&'"'
    WorkSheet.Rows(1).Cells(1).Font.Bold = True 
    WorkSheet.Rows(2).Cells(1).Value = "Отчет на даты: с " & StartS & " по " & StartPO
    WorkSheet.Rows(2).Cells(1).Font.Bold = True
    WorkSheet.Range("A1:H1").Merge
    WorkSheet.Range("A2:H2").Merge    
    ObR = 4
    index = 1 
    RequisitesTabMain = 'Задача ID;Задание ID;Исполнитель;Дата выполнения;Срок задания;Результат;Просрочка;Ссылка на задание'       
    foreach ReqName in CSubString(RequisitesTabMain; ';')
       Progress.Next
        WorkSheet.Rows(ObR).Cells(index).Value = ReqName
        WorkSheet.Rows(ObR).Cells(index).Font.Bold = True
        WorkSheet.Rows(ObR).Cells(index).HorizontalAlignment = -4108
        WorkSheet.Rows(ObR).Cells(index).ColumnWidth = 15
        WorkSheet.Rows(ObR).Cells(index).WrapText = True
        WorkSheet.Rows(ObR).Cells(index).VerticalAlignment = -4108
          WorkSheet.Rows(ObR).Cells(index).Borders(7).LineStyle = 1
          WorkSheet.Rows(ObR).Cells(index).Borders(8).LineStyle = 1
          WorkSheet.Rows(ObR).Cells(index).Borders(9).LineStyle = 1
          WorkSheet.Rows(ObR).Cells(index).Borders(10).LineStyle = 1
          WorkSheet.Rows(ObR).Cells(index).Borders(11).LineStyle = 1
          WorkSheet.Rows(ObR).Cells(index).Borders(12).LineStyle = 1      
        index = index + 1
    endforeach
    
    Stroka2 = ObR + 1
    Stlb2 = 1 
    Indx = 1 
    foreach DataStr in CSubString(Resultat;CR)
      foreach str in CSubString(DataStr;'|')
        if Stlb2 = 2
          IDTask = str  
          WorkSheet.Rows(Stroka2).Cells(Stlb2).Value = str
        else
          WorkSheet.Rows(Stroka2).Cells(Stlb2).Value = str
          if str == 'Выполнено'
            R = 112  
              G = 255         
                B = 150
            WorkSheet.Rows(Stroka2).Cells(Stlb2).Interior.Color = 256*256*R+256*G+B
          endif
          if str == 'Прекращено'
            R = 192  
              G = 192 
                B = 192
            WorkSheet.Rows(Stroka2).Cells(Stlb2).Interior.Color = 256*256*R+256*G+B
          endif
          if str == 'В работе'
            B = 255  
              G = 105            
                R = 105
            WorkSheet.Rows(Stroka2).Cells(Stlb2).Interior.Color = 256*256*R+256*G+B
          endif          
        endif
        Stlb2 = Stlb2 + 1
      endforeach
      WorkSheet.Rows(Stroka2).Cells(Stlb2).Value = ГиперссылкаСоздать(IDTask;"Задание")
      Stroka2 = Stroka2 + 1
      Stlb2 = 1      
    endforeach
    Progress.Text = 'Вот и все!'
    Stroka = Stroka2 - 1
    WorkSheet.Range("A" & ObR & ":H" & Stroka).Borders(7).LineStyle   = 1
    WorkSheet.Range("A" & ObR & ":H" & Stroka).Borders(8).LineStyle   = 1
    WorkSheet.Range("A" & ObR & ":H" & Stroka).Borders(9).LineStyle   = 1
    WorkSheet.Range("A" & ObR & ":H" & Stroka).Borders(10).LineStyle  = 1
    WorkSheet.Range("A" & ObR & ":H" & Stroka).Borders(11).LineStyle  = 1
    WorkSheet.Range("A" & ObR & ":H" & Stroka).Borders(12).LineStyle  = 1
    WorkSheet.Range("A" & ObR & ":H" & Stroka).HorizontalAlignment    = -4108
    WorkSheet.Range("A" & ObR & ":H" & ObR).HorizontalAlignment       = -4108
    //WorkSheet.Range("G1:I1").HorizontalAlignment = -4108
    //WorkSheet.Range("H:J").NumberFormat = "# ##0,0"
    //WorkSheet.Range("D:D").NumberFormat = "dd.mm.yy"
    WorkSheet.Range("A:H").EntireColumn.AutoFit
    WorkSheet.Range("A" & ObR & ":H" & ObR).AutoFilter
    Range = WorkSheet.Range("A" & (ObR + 1) & ":H" & Stroka)
    Range.Sort(WorkSheet.Range("A" & ObR); 1)
    Progress.Hide
    Excel.Visible = TRUE
    ShowMessage('Исполнено. Документ Excel открыт.')

 

Тарас Асачёв: обновлено 08.12.2020 в 20:11
Тарас Асачёв

  Все время теряю. Оставлю на память:

Control : IInplaceHint = Object.Form.Controls.FindControl("InplaceHint")
  Control.Kind = ikhInformation
  Control.Visible = TRUE
  Control.Text = "Хинт Сообщения"

 

Тарас Асачёв

Удаление комментариев из Задачи:

////Event = ServerEvents.GetObjectByName('Event_MEDOProcessInPackages')
//Event.Start
IDTask = InputDialog('*Укажите ИД Задачи';;'Число:0';'Укажите головную задачу')
if Assigned(IDTask)
  Qwery = 'SELECT [JobID]
                ,[Author]
                ,[Text]
                ,[EditDate]
    FROM [DIRECTUM].[dbo].[SBTaskText]
    WHERE TaskID = ' & IDTask
  QweryCo = 'SELECT Count(JobID)
    FROM [DIRECTUM].[dbo].[SBTaskText]
    WHERE TaskID = ' & IDTask
  DataAnal = SQL(Qwery;;' ' & TAB & ' ';'‡')
  NewStr = ''
  ind = 1
  Element = ''
  ShowMessage()
  foreach Data in CSubString(DataAnal;' ' & TAB & ' ')
    ID        = SubString(Data;'‡';1)
    User      = SubString(Data;'‡';2)
    Text      = SubString(Data;'‡';3)
    EditDate  = SubString(Data;'‡';4)
    NewStr = AddSubString(ind & '. ID:' & ID & ' | Исполнитель: ' & ServiceFactory.GetUserByID(User).FullName & ' | ' & Text;NewStr;'##')
    if Assigned(ID)
      Count = 'SELECT Count(XRecID)
      FROM [DIRECTUM].[dbo].[SBTaskText]
      WHERE JobID = ' & ID
      Peremennaya = ID & ' (Исполнитель - ' & ServiceFactory.GetUserByID(User).FullName&') от ' & ФмтДат('d.m.yy';EditDate) & ' [ '&SQL(Count)&' ]'
      if FindSubString(Peremennaya;Element;',') = 0
        Element = AddSubString(Peremennaya;Element;',')
        ind = ind + 1
      endif
    endif  
  endforeach
  Priznak = 'Признак:' & Element 
  Otvet = InputDialog('*Укажие целевое Задание ';'';Priznak;'По данной задаче было найдено ' & SQL(QweryCo) & ' заданий.';;;)
  if Assigned(Otvet)
    IDOtv = SubString(Otvet;' (';1)
    Count = 'SELECT Count(XRecID)
        FROM [DIRECTUM].[dbo].[SBTaskText]
        WHERE JobID = ' & IDOtv
      Qwery2 = 'SELECT [XRecID]
                      ,[EditDate]
                      ,[Text]
        FROM [DIRECTUM].[dbo].[SBTaskText]
        WHERE JobID = ' & IDOtv
    if SQL(Count) == '1'
      MB = MessageBox('Внимание! Выберите дальнейшее действие!';'У данного задания всего 1 комментарий' & CR & 'Вы хотите его удалить?';'Да|Нет';'Нет';'Нет')
      if MB == 'Удалить'
        MB2 = MessageBox('Внимание! Выберите дальнейшее действие!';'Вы уверены что хотите УДАЛИТЬ данный Комментарий?';'Да|Нет';'Нет';'Нет')
        if MB2 == 'Да'
          KILLQwery = 'DELETE [DIRECTUM].[dbo].[SBTaskText] WHERE XRecID = ' & SubString(SQL(Qwery2);';';1)
            QKL = SQL(KILLQwery)
            ShowMessage('Готово')
        endif 
      endif 
    else     
      MB = MessageBox('Внимание! Выберите дальнейшее действие!';'У данного задания ' & SQL(Count) & ' комментариев.' & CR & 'Вы хотите удалить эти Комментарии?';'Удалить|Отмена';'Отмена';'Отмена')       
      if MB == 'Удалить'
        Execut = SQL(Qwery2;;CR & '--------------------------------------' & CR;CR)
        EditText('Посмотрите на комментарии и определитесь с номером на удаление:' & CR & Execut)
        Qwery3 = 'SELECT [XRecID]
                      ,[EditDate]
        FROM [DIRECTUM].[dbo].[SBTaskText]
        WHERE JobID = ' & IDOtv
        Elem = ''
        foreach komm in CSubString(SQL(Qwery3);'|')
          PPRID   = SubString(komm;';';1)
          PPRDate = ФмтДат('d.m.yy';SubString(komm;';';2))
          Elem = AddSubString(PPRID & ' ' & PPRDate;Elem;',')  
        endforeach
        edittext(Elem)
        Search = InputDialog('*Укажите комментарий на удаление';'';'Признак:'&Elem ;'Выберите Комментарий из списка';;;)
        if Assigned(Search)
          IDK = SubString(Search;' ';1)        
          MB2 = MessageBox('Внимание! Выберите дальнейшее действие!';'Вы уверены что хотите УДАЛИТЬ Комментарий с ID ' & IDK & '?';'Да|Нет';'Нет';'Нет')
          if MB2 == 'Да'
            KILLQwery = 'DELETE [DIRECTUM].[dbo].[SBTaskText] WHERE XRecID = ' & IDK
            QKL = SQL(KILLQwery)
            ShowMessage('Готово')
          endif
        endif
      endif
    endif    
  endif
endif

 

Максим Евсеев

Изменение Текста задачи ( Нужно создать диалог) 

ИДЗадачи = InputDialog("Укажите ИДЗадачи:"; ; "Строка:15")
Если не Assigned(ИДЗадачи)
Exit()
Конецесли
СтарыйТекст=  Format("select
                            SBTaskText.Text
                             from
                            SBTaskText SBTaskText
                             where
                            SBTaskText.TaskID = %s 
                             and JobID is NULL";ИДЗадачи)
Старый = CSQL(СтарыйТекст)

    Dialog = Dialogs.DialogFactory("ДиалогИТЗ").CreateNew()
    Dialog.Requisites('ShortString').Value = ИДЗадачи     //Реквизит строка
    Dialog.Requisites('Text').Value = Старый.Value      //Реквизит Текст
    ShowDialog(Dialog)
   Текст = Dialog.Requisites('Text').Value  
    if Dialog.Result = mrCancel 
      Exit()
    endif
    Dialog = nil


    


 

Изменено = Format("update SBTaskText
set Text = '%s'
where TaskID = %s
and JobID is NULL";ArrayOf(Текст; ИДЗадачи))
SQL(Изменено) 

 

Максим Евсеев: обновлено 24.12.2020 в 09:24
Максим Евсеев: обновлено 24.12.2020 в 09:24
Максим Евсеев: обновлено 24.12.2020 в 09:27
Тарас Асачёв

Максим, Дополню:

IDTask = InputDialog('*Укажите ИД Задачи';;'Число:0';'Укажите головную задачу')
if Assigned(IDTask)
  Qwery = 'SELECT [JobID]
                ,[Author]
                ,[Text]
                ,[EditDate]
    FROM [DIRECTUM].[dbo].[SBTaskText]
    WHERE TaskID = ' & IDTask
  QweryCo = 'SELECT Count(JobID)
    FROM [DIRECTUM].[dbo].[SBTaskText]
    WHERE TaskID = ' & IDTask
  DataAnal = SQL(Qwery;;' ' & TAB & ' ';'‡')
  NewStr = ''
  ind = 1
  Element = ''
  foreach Data in CSubString(DataAnal;' ' & TAB & ' ')
    ID        = SubString(Data;'‡';1)
    User      = SubString(Data;'‡';2)
    Text      = SubString(Data;'‡';3)
    EditDate  = SubString(Data;'‡';4)
    NewStr = AddSubString(ind & '. ID:' & ID & ' | Исполнитель: ' & ServiceFactory.GetUserByID(User).FullName & ' | ' & Text;NewStr;'##')
    if Assigned(ID)
      Count = 'SELECT Count(XRecID)
      FROM [DIRECTUM].[dbo].[SBTaskText]
      WHERE JobID = ' & ID
      Peremennaya = ID & ' (Исполнитель - ' & ServiceFactory.GetUserByID(User).FullName&') от ' & ФмтДат('d.m.yy';EditDate) & ' [ '&SQL(Count)&' ]'
      if FindSubString(Peremennaya;Element;',') = 0
        Element = AddSubString(Peremennaya;Element;',')
        ind = ind + 1
      endif
    endif  
  endforeach
  Priznak = 'Признак:' & Element 
  Otvet = InputDialog('*Укажие целевое Задание ';'';Priznak;'По данной задаче было найдено ' & SQL(QweryCo) & ' заданий.';;;)
  if Assigned(Otvet)
    IDOtv = SubString(Otvet;' (';1)
    Count = 'SELECT Count(XRecID)
        FROM [DIRECTUM].[dbo].[SBTaskText]
        WHERE JobID = ' & IDOtv
      Qwery2 = 'SELECT [XRecID]
                      ,[EditDate]
                      ,[Text]
        FROM [DIRECTUM].[dbo].[SBTaskText]
        WHERE JobID = ' & IDOtv
    if SQL(Count) == '1'
      MB = MessageBox('Внимание! Выберите дальнейшее действие!';'У данного задания всего 1 комментарий' & CR & 'Вы хотите его удалить/изменить?';'Да|Нет';'Нет';'Нет')
      if MB == 'Да'
        MB2 = MessageBox('Внимание! Выберите дальнейшее действие!';' Выберите дальнейшее действие с данным Комментарием.';'Удалить|Изменить|Нет';'Нет';'Нет')
        if MB2 == 'Удалить'
          KILLQwery = 'DELETE [DIRECTUM].[dbo].[SBTaskText] WHERE XRecID = ' & SubString(SQL(Qwery2);';';1)
            QKL = SQL(KILLQwery)
            ShowMessage('Готово')
        endif
        if MB2 == 'Изменить'
            TextIsh = SQL('Select Text FROM [DIRECTUM].[dbo].[SBTaskText] WHERE XRecID = ' & SubString(SQL(Qwery2);';';1))
            TextIsh = EditText(TextIsh)
            EditQwery = "UPDATE [DIRECTUM].[dbo].[SBTaskText] SET [TEXT] = '" & TextIsh & "'
            WHERE XRecID = " & SubString(SQL(Qwery2);';';1)
            QED = SQL(EditQwery)
            ShowMessage('Готово')
          endif 
      endif 
    else     
      MB = MessageBox('Внимание! Выберите дальнейшее действие!';'У данного задания ' & SQL(Count) & ' комментариев.' & CR & 'Вы хотите Удалить/Изменить эти Комментарии?';'Удалить/Изменить|Отмена';'Отмена';'Отмена')       
      if MB == 'Удалить/Изменить'
        Execut = SQL(Qwery2;;CR & '--------------------------------------' & CR;CR)
        EditText('Посмотрите на комментарии и определитесь с номером на удаление:' & CR & Execut)
        Qwery3 = 'SELECT [XRecID]
                      ,[EditDate]
        FROM [DIRECTUM].[dbo].[SBTaskText]
        WHERE JobID = ' & IDOtv
        Elem = ''
        foreach komm in CSubString(SQL(Qwery3);'|')
          PPRID   = SubString(komm;';';1)
          PPRDate = ФмтДат('d.m.yy';SubString(komm;';';2))
          Elem = AddSubString(PPRID & ' ' & PPRDate;Elem;',')  
        endforeach
        edittext(Elem)
        Search = InputDialog('*Укажите комментарий на удаление';'';'Признак:'&Elem ;'Выберите Комментарий из списка';;;)
        if Assigned(Search)
          IDK = SubString(Search;' ';1)        
          MB2 = MessageBox('Внимание! Выберите дальнейшее действие!';'Вы уверены что хотите УДАЛИТЬ Комментарий с ID ' & IDK & '?';'Удалить|Изменить|Нет';'Нет';'Нет')
          if MB2 == 'Удалить'
            KILLQwery = 'DELETE [DIRECTUM].[dbo].[SBTaskText] WHERE XRecID = ' & IDK
            QKL = SQL(KILLQwery)
            ShowMessage('Готово')
          endif
          if MB2 == 'Изменить'
            TextIsh = SQL('Select Text FROM [DIRECTUM].[dbo].[SBTaskText] WHERE XRecID = ' & IDK)
            TextIsh = EditText(TextIsh)
            EditQwery = "UPDATE [DIRECTUM].[dbo].[SBTaskText] SET [TEXT] = '" & TextIsh & "'
            WHERE XRecID = " & IDK
            QED = SQL(EditQwery)
            ShowMessage('Готово')
          endif
        endif
      endif
    endif    
  endif
endif
 
 

 

Тарас Асачёв

Пользовательский выбор с использованием строки запроса:

SPR = References.ЦФО.GetComponent
ADD_WHERE_VARIABLE_NAME = "AddWhereCondition" 
Conditions = Format("MBAnalit.%s is not NULL";SPR.Requisites("Подразделение").SQLFieldName)  
Object.Environment.SetVar(ADD_WHERE_VARIABLE_NAME; Conditions)        
SelectFromReferenceAction('ЦФО'; SelectMode; InputValue; Requisite; nil;;)

 

Тарас Асачёв
TextReplace = Text
TextReplace = Replace(TextReplace;Символ(10);' ')
TextReplace = Replace(TextReplace;Символ(160);' ')
TextReplace = Replace(TextReplace;Символ(173);' ')
TextReplace = Replace(TextReplace;Символ(8192);' ')
TextReplace = Replace(TextReplace;Символ(8193);' ')
TextReplace = Replace(TextReplace;Символ(8194);' ')
TextReplace = Replace(TextReplace;Символ(8195);' ')
TextReplace = Replace(TextReplace;Символ(8196);' ')
TextReplace = Replace(TextReplace;Символ(8197);' ')
TextReplace = Replace(TextReplace;Символ(8198);' ')
TextReplace = Replace(TextReplace;Символ(8199);' ')
TextReplace = Replace(TextReplace;Символ(8200);' ')
TextReplace = Replace(TextReplace;Символ(8201);' ')
TextReplace = Replace(TextReplace;Символ(8202);' ')
TextReplace = Replace(TextReplace;Символ(8203);' ')
TextReplace = Replace(TextReplace;Символ(8204);' ')
TextReplace = Replace(TextReplace;Символ(8205);' ')
TextReplace = Replace(TextReplace;Символ(8206);' ')
TextReplace = Replace(TextReplace;Символ(8207);' ')
TextReplace = Replace(TextReplace;Символ(8239);' ')
TextReplace = Replace(TextReplace;'  ';' ')
Result = Trim(TextReplace)
Тарас Асачёв: обновлено 02.03.2021 в 15:14
Тарас Асачёв

Удаление пользователя из групп, закрытие работника, отключение пользователя:

Сценарий.

LogList = now()
IDList = ''
RefRab = References.РАБ.GetComponent
View = RefRab.CreateView('Главное')
View.ViewMode =  vmSelect 
View.MultiSelection = TRUE
View.MainForm.Show
if View.MainForm.Result = mrOK
    RecCount = View.SelectedRecordCount 
    Index = 0
    while Index < RecCount 
      IDList = AddSubString(View.SelectedRecordsID(Index);IDList;';')
      Index = Index + 1
    endwhile
endif
foreach RabID in CSubString(IDList;';')
  RAB     = References.РАБ.GetObjectByID(RabID)
  LogList = AddSubString(RAB.SYSREQ_NAME;LogList;CR)
  User    = Rab.Requisites("Пользователь").AsString
  if Assigned(User)
    UserRef = References.SYSREF_USERS_REFERENCE.GetObjectByCode(User)
    UserRef.SYSREQ_STATE = 'Закрытая'
    LogList = AddSubString('СпрПользователь закрыт';LogList;CR)
    UserRef.Save
    Login   = SubString(SubString(UserRef.Requisites("ISBDescription").DisplayText;'(';2);')';1)
    SET     = UserRef.DetailDataSet(1)
    SET.First
    IDspr   = SET.Requisites('ИДСпрТ').Value
    FCTUser = References.SYSREF_USERS.GetObjectByID(IDspr)
    FCTUser.OpenRecord
    Groups = FCTUser.DetailDataSet(1)
    foreach Group in Groups
      Flt = Group.ГруппаТ
      if not ((Flt == 'ВСЕ') or (Flt =='main')) 
        Group.Delete
        FCTUser.Save
      endif
      LogList = AddSubString('Группы очищены';LogList;CR)
    endforeach
    QweryKill = "UPDATE [DIRECTUM].[dbo].[MBUser] SET [UserStatus] = 'О' WHERE [UserLogin] = '"&Login&"'"
    SQL(QweryKill)
    LogList = AddSubString('Пользователь отключен';LogList;CR)
    Result = 1
  else
    Result = 0
  endif
  RAB.SYSREQ_STATE = 'Закрытая'
  RAB.ВидДолжности = null
  RAB.Строка = 'Сотрудник уволен'
  LogList = AddSubString('Пользователь закрыт';LogList;CR)
  RAB.Save
  LogList = AddSubString('--------------------------------';LogList;CR)
endforeach

EditText(LogList)

 

Тарас Асачёв

Заполнение Группы пользователей путем копирования из других групп:

Group = References.SYSREF_USER_GROUPS.GetComponent
View = Group.CreateView('Главное')
View.ViewMode =  vmSelect 
View.MultiSelection = FALSE
ShowMessage('Выберите целевую группу.')
View.MainForm.Show
if View.MainForm.Result = mrOK
  GroupCel = References.SYSREF_USER_GROUPS.GetObjectByID(View.SelectedRecordsID(0))
else
  exit()
endif
Userlist = ServiceFactory.GetUserList
DDSGROUP = GroupCel.DetailDataSet(1)
Group = References.SYSREF_USER_GROUPS.GetComponent
View = Group.CreateView('Главное')
View.ViewMode =  vmSelect 
View.MultiSelection = TRUE
ShowMessage('Выберите Группы-доноры.')
View.MainForm.Show
if View.MainForm.Result = mrOK
  ind = 0
  while ind < View.SelectedRecordCount
    GroupName = References.SYSREF_USER_GROUPS.GetObjectByID(View.SelectedRecordsID(ind))
    DDSGR = GroupName.DetailDataSet(1)
    DDSGR.OpenRecord
    foreach gpol in DDSGR
      Userlist.Add(ServiceFactory.GetUserByName(gpol.Requisites("ПользовательТ").Value)) 
    endforeach
    DDSGR = nil
    ind = ind + 1
  endwhile  
  foreach user in Userlist
    DDSGROUP.Append
    DDSGROUP.ПользовательТ = user.Name
  endforeach
  GroupCel.Form.Show  
endif

 

Тарас Асачёв

Чего многим не хватает:

Функция ИзмВремя(GЧасть;GВремя;GЗначение):

PN = False
PH = False
Дата = SubString(GВремя;' ';1) 
Время = SubString(GВремя;' ';2)
H = SubString(Время;':';1)
N = SubString(Время;':';2)
S = SubString(Время;':';3)
if GЧасть == 's'
  NewS = S + GЗначение
  if NewS > 59
    NewS = (NewS - 60)
    N = N + 1
    PN = TRUE
    GЗначение = 0
  endif
  S = NewS
endif
if (GЧасть == 'n') or (PN)
  NewN = N + GЗначение
  if NewN > 59
    NewN = (NewN - 60)
    H = H + 1
    PH = TRUE
    GЗначение = 0
  endif
  N = NewN
endif
if (GЧасть == 'h') or (PH)
  NewH = H + GЗначение
  if NewH > 23
    NewH = (NewH - 24)
    Дата = ИзмДат('Д';Дата;1)
  endif
  H = NewH
endif
if H < 10
  H = 0 & H
endif
if N < 10
  N = 0 & N
endif
if S < 10
  S = 0 & S
endif

Result = Дата & ' ' & H & ':' & N & ':' & S 

 

Анатолий Придыбайло

Тарас, а почему не подошел метод GetRelativeDate фабрики служебных объектов IServiceFactory?

Анатолий Придыбайло: обновлено 19.03.2021 в 18:58
Сергей Меньших

Анатолий, как минимум 2 аргумента - смещение у штатного метода только положительное и с учетом календаря рабочего времени.

Тарас Асачёв

Анатолий, из-за описания: "при получении значения относительной даты будет игнорироваться время." А мне как раз надо было время менять.

Анатолий Придыбайло

Сергей, с календарем я согласен, а вот утверждение что смещение только положительное, неверно, метод работает и с отрицательными смещениями. Тем более что смещение в обратную сторону и в функции Тараса не работает.

Тарас, да когда смещение идет по дням действительно пропадает время, но это решается небольшой проверкой и добавлением части с временем. У вашей функции есть недостатки:
1. Не работает с отрицательным смещением
2. Неправильно обрабатывает смещения с значениями превышающие, для секунд и минут 60, а для часов 24

Решил развить вашу функцию и добавить в нее параметр смещения времени с учетом календаря рабочего времени и устранить недостатки:

if not UseCalendar
  StrDate = SubString(StartDate; " "; 1)
  StrTime = SubString(StartDate; " "; 2)
  H = SubString(StrTime; ":"; 1)
  M = SubString(StrTime; ":"; 2)
  S = SubString(StrTime; ":"; 3)
  if NumberType == dotDays
    StrDate = ChangeDate("D"; StrDate; Number)
  else
    PM = FALSE
    PH = FALSE
    if NumberType == dotSeconds
      NewS = S + Number
      if Number > 0
        while NewS > 59
          NewS = NewS - 60
          M = M + 1
          PM = TRUE
        endwhile
      else
        while NewS < 0
          NewS = 60 + NewS
          M = M - 1
          PM = TRUE
        endwhile        
      endif
      S = NewS
      Number = 0
    endif
    if NumberType == dotMinutes or PM
      NewM = M + Number
      if Number > 0
        while NewM > 59
          NewM = NewM - 60
          H = H + 1
          PH = TRUE
        endwhile
      else
        while NewM < 0
          NewM = 60 + NewM
          H = H - 1
          PH = TRUE
        endwhile        
      endif      
      M = NewM
      Number = 0
    endif
    if NumberType == dotHours or PH
      NewH = H + Number
      if Number > 0
        while NewH > 23
          NewH = NewH - 24
          StrDate = ChangeDate("D"; StrDate; 1)
        endwhile
      else
        while NewH < 0
          NewH = 24 + NewH
          StrDate = ChangeDate("D"; StrDate; -1)
        endwhile        
      endif       
      H = NewH
    endif
    if H < 10 and H > 0
      H = 0 & H
    endif
    if M < 10 and M > 0
      M = 0 & M
    endif
    if S < 10 and S > 0
      S = 0 & S
    endif
  endif
  StrRelativeDate = StrDate & " " & H & ":" & M & ":" & S
else
  if not Assigned(UserID)
    RelativeDate = ServiceFactory.GetRelativeDate(StartDate; Number; NumberType)
  else
    RelativeDate = ServiceFactory.GetRelativeDate(StartDate; Number; NumberType; UserID)
  endif
  if NumberType = dotDays
    StrRelativeDate = RelativeDate & " " & SubString(StartDate; " "; 2)
  else
    StrRelativeDate = DateToStr(RelativeDate; dftDateTime; cltInternal)
  endif
endif
Result = StrRelativeDate

Пример сценария:

StrDate = '10.03.2021 10:13:45'
StartDate = StrToDate(StrDate; dftDateTime; cltInternal)
Number = -30
NumberType = dotHours
UseCalendar = False
Анатолий Придыбайло: обновлено 21.03.2021 в 16:54
Сергей Меньших

Анатолий, в 5.4 не работает 100% отрицательное смещение.

и не только это в 5.4 кривое и нихрена не правится разработчиками даже в 5.8.

Сергей Меньших: обновлено 21.03.2021 в 21:56
Анатолий Придыбайло

Сергей, проверил на имеющихся виртуалках работает на 5.6-5.8 не работает на 5.2. 5.4 нет под рукой.

Сергей Меньших

Анатолий, можете мне поверить - на 5.4.1 не работает =)

Тарас Асачёв

Анатолий,  Спасибо за развитие темы. Это же просто "шпаргальник", так что тут какой блок не возьми - все можно и местами нужно дорабатывать. 

 

Тарас Асачёв

Новинка на размышления:

Minus2Hours = ИзмВремя(Now();-2;dotHours;FALSE)
Minus8Hours = ИзмВремя(Now();-8;dotHours;FALSE)
QWERY2 = "SELECT DISTINCT([CurrentUserID])
 FROM [DIRECTUM].[dbo].[SBAdaptiveUsers]
 WHERE LastReadDate > '"& Minus2Hours &"'"
ActionUser = SQL(QWERY2;;',')
QWERY8 = "SELECT DISTINCT([CurrentUserID])
 FROM [DIRECTUM].[dbo].[SBAdaptiveUsers]
 WHERE LastReadDate > '"& Minus8Hours &"' 
 and LastReadDate < '"& Minus2Hours &"' 
 and not ([CurrentUserID] in ("& ActionUser &"))"
FailUser = SQL(QWERY8;;CR) 
UsersID = ''
foreach user in CSubString(FailUser;CR)
  if User > 0
    UsersID = AddSubString(user;UsersID;',')
  endif
endforeach
UserRef = References.SYSREF_USERS_REFERENCE.GetComponent
Addwhere = UserRef.AddWhere(format("%s.%s in (%s)";ArrayOf(UserRef.TableName;UserRef.Requisites(SYSREQ_ID).SQLFieldName;UsersID)))
View = UserRef.CreateView('Главное')
View.ViewMode = vmSelect 
View.MultiSelection = TRUE
View.MainForm.Show
// И смотрим на список неактивных 2 часа пользователей


 

Тарас Асачёв: обновлено 31.03.2021 в 10:56
Тарас Асачёв

Если вдруг кто-то не знал:

  DeusVult= '"C:\Program Files (x86)\DIRECTUM Company\DIRECTUM 5.7\SASessionSrvInfo.exe" -S=SERVER -D=DIRECTUM -WA -DU=' & LoginUser
  if Assigned(DeusVult)
    CMD = CreateObject("WScript.Shell")
    CMD.Run(DeusVult;1;True)
  endif

Этот пост никак не связан с предыдущим! Не надо их смешивать)

Тарас Асачёв: обновлено 31.03.2021 в 10:57
Тарас Асачёв

Коллекция справочника в ТМ:

Komissia = Params.ValueByName('Комиссия') // Коллекция
spisok = ''
ind = 1
foreach RefInfo in Komissia.Value
  spisok = AddSubString(ind & '. ' & RefInfo.Name; spisok; CR)
  ind = ind + 1
endforeach

 

Тарас Асачёв

Тарас, На основании этого сделан инструмент Администратора, для работы с заблокированными полями в карточках справочников:

SPR = GetRefTypeByRefID(Object.ID)
Spravochnik = CreateReference(SPR)
Priznak = ''
try
  ind = 0
  while ind < 1000
    PR = Spravochnik.RequisiteByIndex(ind)    
    Priznak = AddSubString(PR.Title & '("' & PR.Name & '")';Priznak;',')   //  & ' | ' & PR.DataType
    ind = ind + 1  
  endwhile
except
  InputDi = InputDialog('Какое поле надо разблокировать?';'';'Признак:'&Priznak;'')
  if Assigned(InputDi)
    Recv = SubString(SubString(InputDi;'("';2);'")';1)
    if Object.Form.Controls.FindControlByRequisite(Object.Requisites(PR.Name)).Visible    
      Object.Form.Controls.FindControlByRequisite(Object.Requisites(Recv)).Enabled = TRUE
      Object.Form.Controls.FindControlByRequisite(Object.Requisites(Recv)).ReadOnly = FALSE
    endif
  endif                  
endexcept              

 

Тарас Асачёв
TextList = list
Max = КолПодстр(TextList;';')
RND = RANDOM(Max)
//RND = SQL('SELECT RAND()*'&MAX)
//result = Окр(RND;Tch)
Result = SubString(TextList;';';RND)

 

Дмитрий Зайцев

День добрый! Тарас, можете немного подсказать по 5. пункту - Отправка почты с вложениями. 

 RassEmail = Params.ValueByName("email2").Value

Значение - email2 - в данном случае откуда берется? Статическое значение или из справочника?

Тарас Асачёв

Дмитрий, А разве имеет значение? Судя по контексту, строка с адресом берется из параметра, а уже как его туда занести - дело ваше. Его можно брать из документа, справочника, константы, внесено статично, запросом от пользователя. Значения не имеет. 

Тарас Асачёв

Годовая статистика:

Year = InputDialog('*Год';ФмтДат('YY';today());'Строка:4';'Укажите год статистики') + 0
CounDoc = SQL("SELECT Count([XRecID])     
  FROM [DIRECTUM].[dbo].[SBEDoc]
  WHERE [CreateDate] >= '01.01."&Year&"' 
  AND [CreateDate] <= '31.12."&Year&"'")
CountTask = SQL("SELECT Count([XRecID])      
  FROM [DIRECTUM].[dbo].[SBTask]
  WHERE StartDate >= '01.01."&Year&"' 
  AND StartDate <= '31.12."&Year&"'")
CountTaskTM = SQL("SELECT Count([XRecID])      
  FROM [DIRECTUM].[dbo].[SBTask]
  WHERE StartDate >= '01.01."&Year&"'
  AND StartDate <= '31.12."&Year&"'
  AND StandardRoute is not Null")
RKK = SQL("SELECT COUNT([Analit])
  FROM [DIRECTUM].[dbo].[MBAnalit]
  WHERE [Vid] = 3174
  AND Date2 >= '01.01."&Year&"'
  AND Date2 <= '31.12."&Year&"'")
ShowMessage('Создано документов: ' & CounDoc & CR &
'Создано Задач: ' & CountTask & CR &
'Из них по Типовому маршруту: ' & CountTaskTM & CR &
'Создано РКК: ' & RKK)

 

Тарас Асачёв

Чистка групп пользователей от мертвечины:

Group = References.SYSREF_USER_GROUPS.GetComponent
View = Group.CreateView('Главное')
View.ViewMode =  vmSelect 
View.MultiSelection = TRUE
View.MainForm.Show
spisok = ''
if View.MainForm.Result = mrOK
  ind = 0
  while ind < View.SelectedRecordCount
    GroupName = References.SYSREF_USER_GROUPS.GetObjectByID(View.SelectedRecordsID(ind))
    DDSGR = GroupName.DetailDataSet(1)
    DDSGR.OpenRecord
    foreach gpol in DDSGR
      Login = ServiceFactory.GetUserByName(gpol.Requisites("ПользовательТ").Value).Name
      QweryKill = "Select Count([UserLogin]) FROM [DIRECTUM].[dbo].[MBUser] WHERE [UserStatus] = 'О' and [UserLogin] = '"&Login&"' "
      Count = SQL(QweryKill)
      if Count > 0
        spisok = AddSubString('Исключен работник: ' & gpol.Requisites("ПользовательТ").DisplayText;spisok;CR)
        gpol.Delete
      endif
    endforeach
    DDSGR = nil
    GroupName.Save
    ind = ind + 1
  endwhile  
  EditText(spisok) 
endif

 

Тарас Асачёв

Чистка подразделений от закрытых работников:

Group = References.ПОД.GetComponent
View = Group.CreateView('Главное')
View.ViewMode =  vmSelect 
View.MultiSelection = TRUE
View.MainForm.Show
spisok = ''
Resultat = ''
if View.MainForm.Result = mrOK
  ind = 0
  while ind < View.SelectedRecordCount
    IDPodr = View.SelectedRecordsID(ind)
    spisok = AddSubString(IDPodr;spisok;',')    
    ind = ind + 1
  endwhile
  
  Rab = References.РАБ.GetComponent
  Addwh = Rab.AddWhere(format("MBAnalit.%s in (%s) and MBAnalit.%s = 'З'";ArrayOf(Rab.Requisites("Подразделение").SQLFieldName;spisok; Rab.Requisites(SYSREQ_STATE).SQLFieldName)))
  Rab.Open
  if Rab.RecordCount > 0
    foreach str in Rab
      Empl = References.РАБ.GetObjectByID(str.ID)
      Empl.Подразделение = 'Д000039'
      Empl.Save
      Resultat = AddSubString('работник ' & Empl.SYSREQ_NAME & ' перенесен в подразделение "УВОЛЕННЫЕ"';Resultat;CR)
    endforeach
  endif 
  if Assigned(Resultat)
    EditText(Resultat)
  else
    ShowMessage('Работников на перенос не обнаружено!')
  endif    
endif

Надо создать подразделение "Уволенные" и поправить код с учетом кода подразделения.

Тарас Асачёв

Специфическая тема.

Изменение номера версии документа:

InptDlg = InputDialog('*ID документа|*На какую версию меняем|*Какой номер изменяем';'|2|1';'Number:0|Number:0|Number:0';;;;'')
ID = SubString(InptDlg;'|';1)
NewVersion = SubString(InptDlg;'|';2)
OldVersion = SubString(InptDlg;'|';3)
Doc = EDocuments.GetObjectByID(ID)
SQL = "UPDATE SBEDocVer SET Number = " & NewVersion & " WHERE EDocID = " & ID & " AND Number = " & OldVersion
SQL(SQL)
Edittext('Произведено обновление: У документа ' & Doc.SYSREQ_EDOC_NAME & ' версия №' & OldVersion & ' была изменена на ' & NewVersion)

 

Тарас Асачёв

Редактирование Групп Пользователей:

Group = References.ГПЛ.GetComponent
AddwhereGroup = Group.AddWhere(Format("%s.%s = 'Д'"; ArrayOf(Group.TableName; Group.Requisites('Состояние').SQLFieldName)))   
  View = Group.CreateView('Главное')
  View.ViewMode =  vmSelect 
  View.MultiSelection = FALSE
  View.MainForm.Show
  if View.MainForm.Result = mrOK
    GroupName = References.SYSREF_USER_GROUPS_REFERENCE.GetObjectByID(View.SelectedRecordsID(0))
    //GroupName = ServiceFactory.GetGroupByID(View.SelectedRecordsID(0))
  else
    exit()
  endif
  
MSG = MessageBox("Минутку внимания."; 'Что необходимо сделать?'; 'Удалить пользователей|Оставить пользователей|Добавить пользователей|Отмена'; 'Отмена'; 'Отмена') 
if MSG == "Удалить пользователей"  
  Userlist = ''
  DDSGROUP = GroupName.DetailDataSet(1)
  DDSGROUP.OpenRecord
  foreach TabPol in DDSGROUP
    Userlist = AddSubString(ServiceFactory.GetUserByCode(TabPol.Requisites("ПользовательТ").Value).ID; Userlist; ',') 
  endforeach   
  Ref = CreateReference('ПОЛ')       // Указываем справочник 
  Addwhere = Ref.AddWhere(Format("%s.%s in (%s)"; ArrayOf(Ref.TableName; Ref.Requisites('ИД').SQLFieldName; Userlist)))
    View = Ref.CreateView('Главное')
    View.ViewMode =  vmSelect 
    View.MultiSelection = TRUE
    ShowMessage('Выберите пользователей на удаление!')
    View.MainForm.Show
    index = 0
    if View.MainForm.Result = mrOK
      FinalText = Сейчас() & CR
      while index < View.SelectedRecordCount
        IDUser = View.SelectedRecordsID(index)
        foreach gpol2 in DDSGROUP
          if IDUser == ServiceFactory.GetUserByCode(gpol2.Requisites("ПользовательТ").Value).ID
             gpol2.Delete 
             FinalText = FinalText & 'Из группы "' & GroupName.SYSREQ_NAME & '" Удален пользователь: ' & ServiceFactory.GetUserByID(IDUser).FullName & CR 
          endif 
        endforeach     
        index = index + 1
      endwhile    
      GroupName.Save
      DDSGROUP.CloseRecord
      FinalText = FinalText & Сейчас()
      EditText(FinalText)  
    endif
endif

if MSG == "Оставить пользователей"
  Userlist = ''
  ListOst = ''
  DDSGROUP = GroupName.DetailDataSet(1)
  DDSGROUP.OpenRecord
  foreach TabPol in DDSGROUP
    Userlist = AddSubString(ServiceFactory.GetUserByCode(TabPol.Requisites("ПользовательТ").Value).ID; Userlist; ',') 
  endforeach   
  Ref = CreateReference('ПОЛ')    
  Addwhere = Ref.AddWhere(Format("%s.%s in (%s)"; ArrayOf(Ref.TableName; Ref.Requisites('ИД').SQLFieldName; Userlist)))
    View = Ref.CreateView('Главное')
    View.ViewMode =  vmSelect 
    View.MultiSelection = TRUE
    ShowMessage('Выберите пользователей которых надо ОСТАВИТЬ в группе!')
    View.MainForm.Show
    index = 0
        if View.MainForm.Result = mrOK
      FinalText = Сейчас() & CR
      while index < View.SelectedRecordCount
        IDUser = View.SelectedRecordsID(index)
        ListOst = AddSubString(IDUser; ListOst; ',')     
        index = index + 1
      endwhile
      foreach gpol2 in DDSGROUP
        if FindSubString(ServiceFactory.GetUserByCode(gpol2.Requisites("ПользовательТ").Value).ID; ListOst; ',') = 0          
           gpol2.Delete
           FinalText = FinalText & 'Из группы "' & GroupName.SYSREQ_NAME & '" Удален пользователь: ' & ServiceFactory.GetUserByCode(gpol2.Requisites("ПользовательТ").Value).FullName & CR 
        endif 
      endforeach   
      GroupName.Save
      DDSGROUP.CloseRecord
      FinalText = FinalText & Сейчас()
      EditText(FinalText)  
    endif
endif

if MSG == "Добавить пользователей"
  Userlist = ''
  DDSGROUP = GroupName.DetailDataSet(1)
  try
    DDSGROUP.OpenRecord
  except  
  endexcept    
  Ref = CreateReference('ПОЛ')       // Указываем справочник 
  Addwhere = Ref.AddWhere(Format("%s.%s = 'Д'"; ArrayOf(Ref.TableName; Ref.Requisites('Состояние').SQLFieldName)))
    View = Ref.CreateView('Главное')
    View.ViewMode =  vmSelect 
    View.MultiSelection = TRUE
    ShowMessage('Выберите пользователей которых надо добавить в группу!')
    View.MainForm.Show
    index = 0
    FinalText = Сейчас() & CR
    if View.MainForm.Result = mrOK
      while index < View.SelectedRecordCount
        IDUs = View.SelectedRecordsID(index)
        CodeUs = ServiceFactory.GetUserByID(Trim(IDUs)).Code
        FinalText = FinalText & 'В группу "' & GroupName.SYSREQ_NAME & '" добавлен пользователь: ' & ServiceFactory.GetUserByID(Trim(IDUs)).FullName & CR
        DDSGROUP.Append
        DDSGROUP.ПользовательТ = CodeUs
        index = index + 1
      endwhile        
    endif
    GroupName.Save
    DDSGROUP.CloseRecord
    FinalText = FinalText & Сейчас()
    EditText(FinalText) 
endif

 

Тарас Асачёв

Папка "Неотработанные"

Criteria = Sender.SearchCriteria
UserID = tasks.CurrentUser.ID
JobsID = SQL("SELECT TOP 1000 [XRecID]
          FROM [DIRECTUM].[dbo].[SBTaskJob]
          WHERE [Kind] = 'J'
          and [State] = 'W'
          and [Executor] = " & UserID;;',')
NotifID = SQL("SELECT TOP 1000 [XRecID]
          FROM [DIRECTUM].[dbo].[SBTaskJob]
          WHERE [Kind] = 'N'
          and [Readed] = 'N'
          and [Executor] = " & UserID;;',')
IDs = ''
if Assigned(JobsID)
  IDs = AddSubString(JobsID;IDs;',')
endif
if Assigned(NotifID)
  IDs = AddSubString(NotifID;IDs;',')
endif
if Assigned(IDs)
  Where = 'Jobs.XRecID in (' & IDs & ')'
  Criteria.AddWhere = Replace(Where;CR;' ')
else
  Where = 'Jobs.XRecID <> Jobs.XRecID'
  Criteria.AddWhere = Replace(Where;CR;' ') 
endif

+ Кнопка "Отметить все Уведомления Прочтенными":

UserID = tasks.CurrentUser.ID
NotifID = SQL("SELECT DISTINCT [XRecID]
          FROM [DIRECTUM].[dbo].[SBTaskJob]
          WHERE [Kind] = 'N'
          and [Readed] = 'N'
          and [Executor] = " & UserID;;',')
IDs = ''
if Assigned(NotifID)
  IDs = AddSubString(NotifID;IDs;',')
endif
if Assigned(IDs)
  SQL("UPDATE [DIRECTUM].[dbo].[SBTaskJob]
  SET [Readed] = 'Y' 
  WHERE [XRecID] in (" & IDs & ")")
else
  ShowMessage('Нет непрочтенных уведомлений')  
endif
Object.Refresh 

 

Тарас Асачёв

Изменение прав на все документы по ВЭД для пользователя или группы:

Input = InputDialog('*Вид документа|*Тип прав|1. Пользователь|2. Группа пользователей';'|Просмотр||';'Аналитика:ВЭД|Признак:Просмотр,Изменение,Полные|Аналитика:ПОЛ|Аналитика:ГПЛ';'Укажите параметры ВЭД и права пользователя или группы')
if Assigned(Input)
  VED = SubString(Input;'|';1)
  Type = SubString(Input;'|';2)
  User = SubString(Input;'|';3)
  Group = SubString(Input;'|';4)
  if (not Assigned(Group)) and (not Assigned(User))
    ShowMessage('Не выбран пользователь/группа пользователей!')
    exit()
  endif
  if Assigned(User)
    Mishen = ServiceFactory.GetUserByCode(User)
  else
    Mishen = ServiceFactory.GetGroupByCode(Group)
  endif  
  Search = Searches.CreateNew(ckEdocument)
  Criterion = Search.SearchCriteria.Add('ISBEDocKind')
  Criterion.Add(VED)
  SearchJob = Search.Execute
  Progress = CreateProgress('Ведется обработка документов ('& SearchJob.Count &')... Ожидайте...';SearchJob.Count;TRUE)
  Progress.Show
  foreach DocVed in SearchJob
    EDoc = EDocuments.GetObjectByID(DocVed.ID)
    Progress.Text = Edoc.SYSREQ_EDOC_NAME    
    FullRights = CreateList()
    WriteRights = CreateList()
    ReadRights = CreateList()
    foreach User1 in EDoc.AccessRights.Managers    
       FullRights.Add(User1.Code;User1)
       if Type == 'Полные'
          FullRights.Add(Mishen.Code;Mishen)
       endif
    endforeach
    foreach User2 in EDoc.AccessRights.Writers
       WriteRights.Add(User2.Code;User2)
       if Type == 'Изменение'
          WriteRights.Add(Mishen.Code;Mishen)
       endif
    endforeach
    foreach User3 in EDoc.AccessRights.Readers
       ReadRights.Add(User3.Code;User3)
       if Type == 'Просмотр'
          ReadRights.Add(Mishen.Code;Mishen)
       endif
    endforeach
    infoDoc = EDoc.Info 
    EDoc = nil
    try
      SetAccessRightsEDoc(infoDoc ; FullRights ; WriteRights; ReadRights)   
    except endexcept     
    Progress.Next
  endforeach
  Progress.Hide
endif

 

Авторизуйтесь, чтобы написать комментарий