Наверно у каждого разработчика или толкового администратора всегда есть некий блокнотик, куда вбиты основные и наиболее часто используемые фрагменты кода. Давайте я начну своей статьей и выпишу свои любимые фрагменты, а вы подхватите! Представьте какой у нас получится Шпаргальник!
И сразу к делу!
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"
В моем блокнотике пока это наиболее популярная подборка. А что есть у вас? Делимся - не стесняемся!
Тарас, сегодня в ударе. Статья на статьёй.
Тоже собираюсь сделать такую копилку. Но пока не много.
Отобразить критерии поиска для механизма поисков:
Число элементов в массиве и перебор элементов:
Реверс списка:
есть немного проще вариант
тут главное не забывать в этой шпаргалке, что это только для стат. роли, для вычисляемой надо Sender передавать =)
Я не использую такой вызов без Try ... Exception. Задачка ведь может и не создаться.
В качестве базы удобных инструментариев, не могу не отметить когда-то найденную здесь библиотеку функций UDL.. Очень много полезного кода было выцеплено оттуда. Уж не знаю кому сказать спасибо, но пригодилась она здорово..
*. Если пользуюсь МД, то собираю в окно результатов все выбранные пользователем значения, разместив их в скрытом листе и отображая в спец. этапе..
*. Часто пользуюсь заполняемым реквизитом типа признак в диалогах, динамически высчитываю ID очередной записи. Ф-я "_GetNextSymvInCount"
Само заполнение реквизита
* Иногда приходилось дебажить таблицы с скрытыми реквизитами, отображает все записи и все реквизиты и их значения переданной DDS
* Полезная и малоиспользуемая фича - объявление переменной сразу в разрезе определенной ТКЭД. Вспоминаю только когда смотрю в блокнот, никак не привыкну
EDoc : IEDocument.TFD_DCTS_EML =
* Всякие формы для проверки реквизитов вовсе записал в конструкции редатора кода ISBL и теперь быстро вызываю, например, оформление "красивых" стен аля
Или, например самое частоиспользуемое в функциях и сценариях, такая обертка
Копилка — это полезно. Объединить копилки — двойная польза. Но сваливать их в кучу в комментариях, наверное, не самый классный способ организации знаний. Смотрите, у нас есть база знаний, есть "Вопросы", есть даже примеры кода в справке. Как считаете, есть ли у какого-то из этих инструментов перспектива превратиться в удобную базу сниппетов для решения типовых задач? Какого функционала от такой базы ожидаете вы? Чего не хватает сейчас? Почему до сих пор в блокнотиках? :)
Мои 5 копеек — список ИД групп пользователей, подчиненных группе "Developers" и просто "рыба" для написания рекурсивных запросов:
Поделюсь и я чем-нибудь
Немного полезных функций для работы с пользователями
LD_AddUserListToUserList
LD_ConvertStringListToUsers
LD_ConvertUsersToStringList
LD_UserListAddUser
LD_UserListDeleteUser
LD_UserListMerge
Прикреплен файл: func_users.zip
Копилка - штука полезная. Тем, кто будет использовать рекомендации Тараса, крайне рекомендую в п.3 вместо вызова исключения при отсутствии нужного документа ставить признак обязательной запрашиваемости у соответствующего параметра; а соответствие вида/типа проверять уже после запроса параметров. Текущий метод из п.3 кастрирует доступные способы инициирования задач по ТМ.
Свою копилку не собирал, но несколько примеров докину:
При разработке типов справочников, событие Сохранение возможность:
Переопределение выбора записи справочника на пользовательский, на примере Работников:
Проверка вхождения текущего пользователя или замещаемых им пользователей в группы (в основном, используется в более сложных условиях для оптимизации скорости ограничения набора данных справочников или доступных реквизитов, но полезно и просто для нормального отображения содержимого справочника с учётом имеющихся замещений):
Алексей Семакин, считаю что полезным будет ввести контекстно-зависимые шаблоны (развить текущий функционал, позволяющий быстро вставлять конструкции try .. except, ...)
Артем, механизм контекстно зависимых шаблонов не закрыт — туда можно добавлять свои шаблоны. Если там не достает какого-то полезного функционала, то смело оформляйте идею.
Но база сниппетов — это другое. На мой взгляд, это общедоступная база готовых примеров кода для решения задач, не обязательно часто встречающихся. Причем для одной и той же задачи сниппетов может быть несколько (один — быстрый, другой — красивый ). Предложить свой сниппет в базу может любой ее пользователь, и его сниппет после модерации, сразу доступен всем. Модерация нужна — кто-то должен следить за тем, чтобы сниппеты, как минимум, удобно и единообразно искались, чтобы не было совсем уж дублирующихся. Сниппеты должны находиться как поисковым запросом по фрагменту сниппета, так и по тегам. Кроме того, нужна возможность просто серфить по базе — когда поиск нужных результатов не дал, я захочу пройти сам по дереву сниппетов и найти что-то близкое к моей задаче. По какому принципу строить дерево, и дерево ли — отдельный вопрос.
Сценарий по удалению пользователей из группы:
Предпросмотр в карточке справочника:
Есть свои ограничения, но в целом это и к отчету можно прикрутить или сделать вычисления на заполнения HTML документа.
Тарас, если я правильно понял, то:
1) try..except понадобился для того, чтобы не свалиться, когда ind перевалит за фактическое количество реквизитов справочника? Чтобы не гадать, лучше вычислить количество реквизитов и ограничить цикл им: IReference.RequisiteCount.
2) ваш "кусочек кода" никак не прокомментирован, и я могу лишь догадываться, что это — получение метаданных о реквизитах главного раздела справочника. Если так, то все это можно выудить одним запросом прямиком из MBVidAnRecv + MBRecvAn. Кажется, там даже кода раза в два меньше получится, и даже цикл не нужен. Собственно вы оттуда же получаете данные, только через объектную модель.
Алексей, Все верно - решение написанное на коленке, но рабочее и универсальное. А Ваш комментарий очень пригодится) Это же чисто информативное решение чтобы не пользоваться подсказками и поиском реквизитов - не более.
В помощь аудитору: Реестр просрочек по маршрутам за период.
Может это конечно не идеально и много чего надо доработать, но работает!
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 открыт.')
Все время теряю. Оставлю на память:
Удаление комментариев из Задачи:
Изменение Текста задачи ( Нужно создать диалог)
Максим, Дополню:
Пользовательский выбор с использованием строки запроса:
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)
Удаление пользователя из групп, закрытие работника, отключение пользователя:
Сценарий.
Заполнение Группы пользователей путем копирования из других групп:
Чего многим не хватает:
Функция ИзмВремя(GЧасть;GВремя;GЗначение):
Тарас, а почему не подошел метод GetRelativeDate фабрики служебных объектов IServiceFactory?
Анатолий, как минимум 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
Анатолий, в 5.4 не работает 100% отрицательное смещение.
и не только это в 5.4 кривое и нихрена не правится разработчиками даже в 5.8.
Сергей, проверил на имеющихся виртуалках работает на 5.6-5.8 не работает на 5.2. 5.4 нет под рукой.
Анатолий, можете мне поверить - на 5.4.1 не работает =)
Анатолий, Спасибо за развитие темы. Это же просто "шпаргальник", так что тут какой блок не возьми - все можно и местами нужно дорабатывать.
Новинка на размышления:
Если вдруг кто-то не знал:
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
Этот пост никак не связан с предыдущим! Не надо их смешивать)
Коллекция справочника в ТМ:
Тарас, На основании этого сделан инструмент Администратора, для работы с заблокированными полями в карточках справочников:
День добрый! Тарас, можете немного подсказать по 5. пункту - Отправка почты с вложениями.
Значение - email2 - в данном случае откуда берется? Статическое значение или из справочника?
Дмитрий, А разве имеет значение? Судя по контексту, строка с адресом берется из параметра, а уже как его туда занести - дело ваше. Его можно брать из документа, справочника, константы, внесено статично, запросом от пользователя. Значения не имеет.
Годовая статистика:
Чистка групп пользователей от мертвечины:
Чистка подразделений от закрытых работников:
Надо создать подразделение "Уволенные" и поправить код с учетом кода подразделения.
Специфическая тема.
Изменение номера версии документа:
Редактирование Групп Пользователей:
Папка "Неотработанные"
+ Кнопка "Отметить все Уведомления Прочтенными":
Изменение прав на все документы по ВЭД для пользователя или группы:
Сообщение админу про упавшую задачу:
Добавлю и я кое-что в копилку.
Пример отчёта по документам определенного ТКЭД с применением Aspose.Cells. Без красивостей, т.к. файл предназначен для последующего разбора BI-системой.
Владислав, Ну наконец-то нормальный комментарий .
Бросаем все, что периодически надо использовать или где есть ценные фрагменты кода.
Работа с регулярными выражениями
Авторизуйтесь, чтобы написать комментарий