Продумана структура базы данных для хранения разнородной информации, с учетом дальнейшего развития проекта, т.к. я не знаю, что я еще захочу прикрутить, ведь мне всегда мало того, что есть, или оно неудобно для меня.
Я уже давно выкладываю части данного проекта, и все таки я близок к его логическому завершению.
Возможности подсистем и программ:
windows-приложение TAG reader. Я использую для:
1) Ведения списка задач.
Хранение информации первоначальной постановки.
Определение целей. Хранение проектной документации в любом формате, в привязке к задаче.
2) Декомпозиция работ и хранение результатов разработки.
3) компоновка/совмещение результатов нескольких решений по категориям (тэгам)
4) Дополнительно веду базу знаний по разработке в c# и 1с (удобно для копипаста, ведения конспектов). Забыл про word, powerpoint и другие буржуйские программы.
Tag and projects (основная база) + skills(расширение)
Подробное описание разработки в публикации
Подсистема управления контентом + автономное мобильное приложение
5) синхронизируется с программой Tag reader. Загружаются справочники TAG и Content.
1 база TAG = 1 пользователь базы Tag and projects (подробное описание обмена в публикации
Windows приложение для управления контентом + модуль обмена с интеграционной базой
6) Разбиение задач на шаги (допустим в привязке к объектам системы) и последовательное их выполнение.
В основную конфигурацию добавлена подсистема "skills". Основной инструмент декомпозиции - планировщик.
Подробное описание в публикации Планировщик с возможностью декомпозиции
а) Связь справочников Tag->Скиллы 1 к 1му.
б) изменение в справочнике тэгов, и связанного с ним контента синхронизируется в подсистему
"Skills" через документ "Регистрация скилла". На форме контента есть кнопка для создания документа, при этом заполняется табличная часть документа по следующему принципу:
б.1) для каждого выделенного тэга дерева формы контента по полю idtag подбирается элемент
справочника "Content" и добавляется строка табличной части.
Если по idtag элемент справочника "Скиллы" не найден, то будет создан новый элемент для уровня
скиллов текущего пользователя.
Строкадокумента.Описание = Tag.Наименование
Строкадокумента.Комментарий = РегистрСведенийЗапись.CopyContent.Content(Отбор.Cont(IdTag = Tag.Id))
Документ делает движения по регистру "План/факт периодический", с установленной датой документа.
При проведении, на дату документа, проверяется наличие записей в регистре после даты документа по регистрируемым скиллам.
в) после регистрации тэг/скилл появляется в дереве планировщика
в.1) возможно изменение описания скилла и комментария, изменения синхронизируются
в справочники "Tag" и "РегистрСведений.CopyContent" по соответствующим полям
в.2) в планировщике возможно разбиение тэга на подзадачи (изменение автоматически не транслируются в подсистему тэгов)
в.3) возможно указание даты плана и статуса решения (статус "в процессе решения" - указана дата плана, и статус "решен" - указана дата факта, возможна отмена скилла, при этом в планировщике он пометится красным цветом)
г) Изменения в регистре "План/факт периодический" производится через документ "Регистрация плана"
г.1) при проведении документа производится проверка наличия более актуальных записей после документа.
г.2) если проверка проведения успешно пройдена, то по изменениям формируются записи в регистр сведений
г.3) для редактирования данных планов у документа существует форма, в которой можно выполнить,
те же действия, что и в планировщике. Дерево скиллов документа полностью наследует функционал
планировщика.
г.4) в дереве скиллов производится подсветка изменений по полям, по сравнению с предыдущим изменением рассматриваемого скилла. Новые элементы декомпозиции, заведенные
рассматриваемым документом, дополнительно помечаются пиктограммами.
г.5) при проведении изменений плана через форму документа, пользователю будет показан отчет о наличии более актуальных данных, если они существуют.
Отчет представляет собой сравнение двух табличных документов определенного формата.
1й таб. документ - текущие данные документа, 2й таб. документ - актуальные данные документа.
Сравнение табличных документов производится через механизмы БСП.
д) для более быстрого указания дат в подсистему "Skills" добавлен понедельный подбор дат.
В поле ввода необходимо вбить текст, например "март", будут подобраны все даты недель марта.
Так же есть возможность заводить дату в поля ввода типа дата в следующих форматах "0903" "09,03" "09.03" "09/03" "09-03" "09+03" "09*03", автоподбором будет подобрана нужная дата текущего года.
По кнопке выбора в поле ввода даты плана/факта откроется форма выбора даты с подбором
начала или конца недели, подбирается дата аналогично автоподбору через ввод слова "Март".
д.1) В подсистеме скиллы есть отчет "История плана по скиллам"
7) Все изменения связанных справочников регистрируются к обмену с базой программы "Tag reader"
через план обмена "Обмен TAG".
Далее модуль обмена - программа "Tag obmen" может загрузить/выгрузить изменения через веб-сервис или текстовые файлы обмена.
Подробное описание обмена в публикации Windows приложение для управления контентом + модуль обмена с интеграционной базой
8) Структура конфигурации интеграционной базы и расширений
8.1) Конфигурация основной базы. Интегрирована с БСП (Базовая функциональность + Подсистема обмен данными + Файлы).
Предназначена для хранения документа "ДействиеВСистеме" и привязки файлов с мобильного устройства (мобильной конфигурации).
Для создания документа из мобильной конфигурации существует сервис MobileAuthen, авторизация в сервисе производится, по переданному логину и паролю (пользователь ИБ, пароль не связан с паролем справочника пользователи).
Логин и пароль указываются в настройках мобильной ИБ и в регистре сведений "пользователи мобильных приложений"
Подробное описание мобильного приложения в публикации Демонстрационный пример онлайн мобильного приложения (для отправки файлов с мобильного устройства)
8.2) Расширение "обмен с мобильными"
Основная рабочая форма модуля "ФормаКонтента"
8.2.а) Основные объекты Справочник.Tag, Справочник.Content (подчинен Tag), РегистрСведений.CopyContent(подчинен Content).
Табличная часть Content.Tags необходима для хранения дополнительной привязки элементов справочника Content к справочнику TAG.
8.2.б) Обмен данными "Обмен TAG". Обмен в формате XDTO по правилам обмена на базе Конвертации 3.0.
Регистрирует изменения по справочникам "Tag" и "Content". В модуль полностью перенесена подсистема "ОбменДанными" из версии БСП, основной конфигурации. Регистрация в модуле обмена производится без использования правил регистрации.
Обмен служит для синхронизации с базой типа TAG (Tag reader).
Подробное описание обмена в публикации Windows приложение для управления контентом + модуль обмена с интеграционной базой
8.2.в) Обмен данными "Обмен с мобильными". Не использует типовые механизмы.
Полностью написанный с нуля модуль обмена в формате JSON. Служит для синхронизации справочников TAG и Content с мобильной конфигурацией. Загрузка с мобильного приложения производится через web/http - сервисы, в зависимости от настроек базы мобильного приложения.
Через web-сервис грузится данные зарегистрированные в плане обмена (отложенная синхронизация при входе в программу или по нажатию на кнопку). Дополнительно для онлайн обмена используется http-сервис. Формат обмена обоих методов не отличается.
Подробное описание обмена и возможности мобильного приложения в публикации
Подсистема управления контентом + автономное мобильное приложение
8.2.г) ОМ "tagСвязкаСоСкиллами" модуль связки с расширением "skills".
Трансляция в объекты расширения "skills" производится при записи связанных объектов.
8.3) Расширение "skills".
8.3.a) Основной объект иерархический справочник "Скиллы".
Для элементов данного справочника возможно заведение описаний и комментариев, и регистрация в планировщике
8.3.б) С помощью документа "Регистрация скилла" выбранный скилл регистрируется в дереве планировщика (задачи к выполнению)
8.3.в) С помощью документа "Регистрация плана" выбранный скилл регистрируется в планировщике и принимает состояние либо
выполнен/либо отменен.
8.3.в) Собственно сама обработка-планировщик и отчет о статусах задач.
8.3.г) ОМ подбора дат
8.3.д) вспомогательные общие модули
9) На рабочий стол своей информационной базы также вывел обработку "Управление окнами" из публикации Управление открытыми окнами сеанса пользователя
К данной публикации прикреплю адаптированное под интеграционную базу расширение "skills", по сравнению с версией источником, из публикации Планировщик с возможностью декомпозиции, выполнены следующие изменения:
1) добавлена форма документа регистрация плана
2) добавлен подбор дат (форма и модуль автоподбора)
3) трансляция данных в структуру расширения "Обмен с мобильными"
4) снято ограничение на количество символов в полях описание и комментарий документов и регистров
5) автоматически подбирается уровень скиллов по выбранному пользователю
Текущая версия расширения "skills" не тестировалась на типовых конфигурациях, базовая разработка ранее проверялась и работала. Запросы по тэгам и скиллам в документах экранированы через
"Если ОбщегоНазначения.ПодситемаСуществует("tagОбменДанными") Тогда"
Версия БСП основной базы на которой тестировалось расширение "3.0.3.341".
Дерево тэгов для подбора в документе "Регистрация скилла" строится независимо от иерархии справочника Tag, по внутренним идентификаторам базы TAG - поле "SortID", в идеале "SortID" - это отметка времени в формате unixepoch.
Но также алгоритм отрисовки дерева учитывает ошибки в этом поле. При заведении нового тэга обменом или вручную, данное поле актуализируется.
Листинг алгоритма приведу ниже:
&НаСервере
Процедура ЗаполнитьДеревоТэгов()
// ++tap
Если Не ОбщегоНазначения.ПодсистемаСуществует("TagContent") Тогда
Элементы.СкиллыУровняПодборТэгов.Видимость = Ложь;
Элементы.ДеревоТэгов.Видимость = Ложь;
Возврат;
КонецЕсли;
errors_Parrent = "";
errors = "";
ДеревоТэгов.ПолучитьЭлементы().Очистить();
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос("ВЫБРАТЬ
|TAG.Ссылка КАК Ссылка,
|TAG.ВерсияДанных КАК ВерсияДанных,
|TAG.ПометкаУдаления КАК ПометкаУдаления,
|TAG.Владелец КАК Владелец,
|TAG.Родитель КАК Родитель,
|TAG.Код КАК Код,
|TAG.Наименование КАК Наименование,
|TAG.Id КАК Id,
|TAG.PathDirSols КАК PathDirSols,
|TAG.IsGroup КАК IsGroup,
|TAG.SortID КАК SortID,
|ЕСТЬNULL(TAG.Родитель.Id, TAG.Id) КАК GroupId,
|TAG.InnerProjID КАК IDproj,
|TAG.Предопределенный КАК Предопределенный,
|TAG.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных
|ПОМЕСТИТЬ TAG
|ИЗ
|Справочник.Tag КАК TAG
|ГДЕ
|TAG.Владелец = &Пользователь");
Запрос.УстановитьПараметр("Пользователь", Объект.Пользователь);
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Выполнить();
nCache = Новый Структура;
count_iteration = 0;
leng = 0;
~xLabel:
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ
|TAG.Childid КАК id,
|TAG.text КАК text,
|ВЫБОР
| КОГДА InnerProj.IDproj ЕСТЬ NULL
| ТОГДА -1
| ИНАЧЕ TAG.IsGroup
|КОНЕЦ КАК IsGroup,
|TAG.Parrent КАК Parrent,
|TAG.ParrentSortID КАК ParrentSortID,
|TAG.SortID КАК TagSortID,
|ВЫБОР
| КОГДА InnerProj.IDproj ЕСТЬ NULL
| ТОГДА 0
| ИНАЧЕ 1
|КОНЕЦ КАК IsProj
|ИЗ
|(ВЫБРАТЬ
| RootTag.Id КАК id,
| TAG.SortID КАК SortID,
| TAG.Наименование КАК text,
| TAG.IsGroup КАК IsGroup,
| RootTag.Id КАК Parrent,
| RootTag.SortID КАК ParrentSortID,
| TAG.Id КАК Childid
|ИЗ
| TAG КАК RootTag
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ TAG КАК TAG
| ПО RootTag.Id = TAG.GroupId"
+ ?((СтрДлина(errors) > 0), " ГДЕ RootTag.id В (" + errors + ") ИЛИ RootTag.GroupId В (" + errors + ")", " ") + "
|) КАК TAG
| ЛЕВОЕ СОЕДИНЕНИЕ TAG КАК InnerProj
| ПО TAG.Childid = InnerProj.IDproj
|УПОРЯДОЧИТЬ ПО
|TAG.ParrentSortID,
|TAG.SortID";
r = Запрос.Выполнить().Выбрать();
tagId = -2147483648;
FlagIsGroup = -1;
parrenttagId = -2147483648;
text = "";
SortID = -2147483648;
tekerrors = "";
Пока r.Следующий() Цикл
NewNode = null;
tagId = r["id"];
text = r["text"];
FlagIsGroup = r["IsGroup"];
parrenttagId = r["Parrent"];
SortID = r["TagSortID"];
isProj = r["IsProj"];
// определение текщего узла
Если (НЕ tagId = parrenttagId) Тогда
// то что внутри рута, ищу в кэше родителей с детьми,
// пройдя рут, полюбому должен быть родитель в кэше (см. сортировку)
NC = nCache_FindNodeByIndex(parrenttagId);
Если Не NC = Неопределено Тогда
Nodes = ДеревоТэгов.НайтиПоИдентификатору(NC).ПолучитьЭлементы();
Иначе
// не найден в кэше, сортировка по SortID (Значит ошибка, повторный запрос должен отрисовать)
Если (Не Найти(tekerrors, Формат(tagId, "ЧГ="))) Тогда
tekerrors = tekerrors + "," + Формат(tagId, "ЧГ=");
КонецЕсли;
Если (Не Найти(tekerrors, Формат(parrenttagId, "ЧГ="))) Тогда
tekerrors = tekerrors + "," + Формат(parrenttagId, "ЧГ=");
КонецЕсли;
Продолжить;
КонецЕсли;
Иначе
Nodes = ДеревоТэгов.ПолучитьЭлементы();
КонецЕсли;
// ищу в кэше родителей с детьми
NewNode = nCache_FindNodeByIndex(tagId);
Если (NewNode = Неопределено) Тогда
NewNode = Nodes.Добавить();
NewNode.text = text;
NewNode.tagId = tagId;
Если КэшСтрокПоIDTag.Свойство(ПолучитьИДКэшаПоИДТэга(tagId)) Тогда
NewNode.ЕстьВДокументе = Истина;
КонецЕсли;
nCache.Вставить(ПолучитьИДКэшаПоИДТэга(tagId), NewNode.ПолучитьИдентификатор());
Иначе
nCache.Вставить(ПолучитьИДКэшаПоИДТэга(tagId), NewNode);
КонецЕсли;
КонецЦикла;
Если (СтрДлина(tekerrors) > 0) Тогда
Если (leng = СтрДлина(tekerrors)) Тогда
count_iteration = count_iteration + 1;
КонецЕсли;
leng = СтрДлина(tekerrors);
Если (СтрДлина(tekerrors) > 0)
И Лев(tekerrors, 1) = "," Тогда
errors = Сред(tekerrors, 2);
КонецЕсли;
Если (count_iteration < 20) Тогда
Перейти ~xLabel;
КонецЕсли;
КонецЕсли;
// --tap
КонецПроцедуры
З.Ы. Все перечисленные публикации имеют исходные файлы проектов и получили свои обновления.
Код старался оформлять в соответствии стандартам 1С.
Тестировалось на версии БСП 3.0.3.341.
Проверено на следующих конфигурациях и релизах:
- Бухгалтерия предприятия, редакция 3.0, релизы 3.0.155.21