Полезный код для программистов 1С (часть 2). Помощник заполнения.

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

В первой части статьи, я показал как мы реализуем механизм управления видимостью (и другими свойствами элементов формы). А также организацию хранения значений реквизитов до изменений, с целью проверки.

Содержание

Продолжение

В этой части мы рассмотрим то, как мы реализуем механизм заполнения табличных частей из данных программы. Да, это та самая пресловутая кнопка "Заполнить", которая как правило, висит над большинством табличных частей и ею даже иногда пользуются. Сразу объясню, почему лично мне не нравится как обычно реализован этот механизм. Возьмем, например, заполнение остатками материалов в документе "Реализация ТМЦ" или остатками долгов в документе "Корректировка долга":

  • считывание всех данных с минимальным ограничением;
  • необходимость после такого заполнения удаления строк, которые не подходят под заданные условия документа;
  • при случайном удалении лишней строки, приходится проворачивать вышестоящие пункты повторно;
  • практически бесполезен при большом количестве информации в программе.

В большинстве случаев, кажется, что реализация подбора будет значительно удобнее. Но, подбор из остатков тоже требует значительных затрат, но уже со стороны программиста (форму нарисуй, унификацию проведи, потом не забудь ее повторно использовать).

Что предлагаю?

Отказаться от кнопки "Заполнить" в том виде, в котором мы привыкли ее видеть. И сделать ее другой:

  • дать возможность пользователям самим влиять на заполнение путем настройки отборов;
  • сохранять результат настройки отборов, с целью повторного заполнения и отображения на форме, чтобы пользователю было понятно;
  • использовать максимально унифицированные механизмы заполнения с минимизацией разнообразных запросов (как правило однотипных) в разных местах программы.

Для этого мы реализовали ряд механизмов, которые приняли как "стандарт" для применения в нашей организации и (как показало время) пользователям понравилось. Хотя привыкли не сразу и пользоваться научились не все.

Подсистема "Помощник заполнения"

Общая схема создания кнопки "Заполнить" в большинстве случаев теперь у нас выглядит так:

  • создаем СКД, куда помещаем запрос на получение данных. СКД хранится в макете прикрепленном к документу (или другому объекту);
  • на форме создаем реквизит "КомпоновщикНастроекКомпоновкиДанных", который при создании формы на сервере инициализируем на основании ранее созданной СКД. Дополнительно к нему добавляем реквизит с типом "Строка" для хранения представления настроек отбора. В случае если настройка пуста, выводим "Нажмите для настройки отбора…" (нагляднее и пользователю понятнее);
  • на форме создаем элемент "Надпись", связываем с нашим реквизитом "Строка", устанавливаем признак "Гиперссылка", добавляем обработчик "Нажатие";
  • при нажатии на элемент с представлением отбора, открываем специальную форму настройки отбора, куда при необходимости передаем все запрещенные поля (недоступные пользователю);
  • при нажатии кнопки "Заполнить" обычно проверяем что настройка отбора содержит один и более элементов. Предупреждаем пользователя, но все равно выполняем заполнение. Для этого получаем ТаблицуЗначений на основании схемы (из макета) и компоновщика (из формы);
  • перед записью формы, сериализуем пользовательскую настройку отбор, сохраняем в реквизит, для повторного восстановления при открытии.

Как видите, ничего нового. Все достаточно просто.

Конечно, мы сделали ряд общих модулей, которые помогают нам быстрее:

  • выполнять инициализацию компоновщика;
  • создавать необходимые реквизиты и элементы на форме;
  • обрабатывать событие "Нажатие" и открывать форму настройки отбора;
  • получать таблицу значений на основании СКД и компоновщика.

По сути это сделано лишь для минимизация кода на стороне конечного объекта и формы. Ниже представлен практически весь код, который необходим для выполнения указанных операций. Результат вы можете видеть на GIF в заголовке (пример из реальной конфигурации).


&НаСервере
Процедура ИнициализацияФормы()

// ПомощникЗаполненияПТБ.Начало
ПомощникЗаполненияПТБ.ИнициализацияКомпоновщикаНастроек(ЭтотОбъект,
"БанкиКомпоновщикНастроек",
Документы.ТестовыйДокументЗаполнениеСКД.ПолучитьМакет("ПомощникЗаполненияПТБ_СКД"),
Объект.ОтборXML);

ПомощникЗаполненияПТБ.ДобавитьПолеНастройкиОтбора(ЭтотОбъект, "БанкиКомпоновщикНастроек", "ГруппаНастройкиОтбораБанки");
// ПомощникЗаполненияПТБ.Конец

КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)

// ПомощникЗаполненияПТБ.Начало
ТекущийОбъект.ОтборXML = ПомощникЗаполненияПТБ.ПолучитьСтрокуДляСохраненияОтбора(ЭтотОбъект, "БанкиКомпоновщикНастроек");
// ПомощникЗаполненияПТБ.Конец

КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьБанки(Команда)

ЗаполнитьБанкиНаСервере();

КонецПроцедуры

&НаСервере
Процедура ЗаполнитьБанкиНаСервере()

ВыбранныеПоля = Новый Массив;
ВыбранныеПоля.Добавить("Банк");

НастройкиОтбора = Новый ОтборКомпоновкиДанных;
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора(НастройкиОтбора,
"Банк.Город", "Г. УФА", ВидСравненияКомпоновкиДанных.Равно);

НастройкиПорядок = Новый Соответствие;
НастройкиПорядок.Вставить("Банк.Наименование", "ВОЗР");

// ПомощникЗаполненияПТБ.Начало
ТаблицаДанных = ПомощникЗаполненияПТБ.ПолучитьТаблицуЗаполнения(ЭтотОбъект,
"БанкиКомпоновщикНастроек",
ВыбранныеПоля,,
НастройкиОтбора,
НастройкиПорядок);
// ПомощникЗаполненияПТБ.Конец

Объект.Банки.Очистить();
Объект.Банки.Загрузить(ТаблицаДанных);

КонецПроцедуры

#Область СлужебныеПроцедурыИФункции_ПТБ_БСП

// ПомощникЗаполненияПТБ.Начало
&НаКлиенте
Процедура Подключаемый_ПомощникЗаполненияОтборНажатие(Элемент, СтандартнаяОбработка)

ЗапрещенныеПоля = Новый Массив;
ЗапрещенныеПоля.Добавить("Банк.Адрес");
ЗапрещенныеПоля.Добавить("Банк.ИмяПредопределенныхДанных");

ПомощникЗаполненияПТБКлиент.ПомощникЗаполненияОтборНажатие(ЭтотОбъект, Элемент, СтандартнаяОбработка, ЗапрещенныеПоля);

КонецПроцедуры
// ПомощникЗаполненияПТБ.Конец

#КонецОбласти

Заключение

На самом деле, мы эту схему применяем теперь практически везде. В формах документов, справочников, подборов. По сути, количество кода незначительно отличается от привычной нам схемы (объект Запрос — Результат — Выбора/ТаблицаЗначений). Но наличие множества настроек отборов, значительно упрощает подбор информации. А сохранение настройки отбора позволяет пользователю легко вспомнить по каким отборам и правилам была заполнена данная табличная часть.

Один из главных плюсов. Иногда, при заполнении или подборе, необходима фильтрация по определенным правилам. Кроме того, порой эти правила должны быть доступны к отключению одним и недоступны другим. При использовании помощника заполнения это легко реализуется, все отборы можно распихать в фиксированные настройки или обычные, в зависимости от пользователей и доступа. При этом пользователи могут видеть какие отборы на самом деле установлены.

Переход на данную схема начался около года назад, а большинство решений написано задолго до этого, но как показала практика: переезд на использование "ПомощникаЗаполнения" происходит достаточно быстро. В большинстве случаев достаточно просто перетащить запрос, немного настроить доступность полей для отбора, и разместить все необходимые команды (которые на самом деле можно просто разместить в заранее подготовленном шаблоне). Так что не надо бояться переделывать старые решения, ведь все что "работает" вовсе не обязательно что "хорошо".

P.S. Во вложении, вы найдете конфигурацию, в которой обрезано все что только можно, кроме функционала необходимого для работы данной подсистемы. Общие модули из 1С:БСП не брать, они урезаны, а то и вовсе обескровлены. Оставлены только чтобы синтаксический контроль проходил.

14 Comments

  1. triviumfan

    Обычно такое реализуется внешней подключаемой обработкой заполнения ТЧ, но ваше решение довольно удобно и универсально.

    Хотя, редко вообще где пользуются таким заполнением 🙂

    Reply
  2. triviumfan

    (1) А можно ведь сделать это и внешней… было бы круто. Сначала принудительно вызывается форма с отбором, а затем заполнение. Или сохраняемые настройки запилить, чтобы по умолчанию заполнение было таким, а хочешь менять — иди в настройки отбора компоновщика.

    Reply
  3. vandalsvq

    (0), (1) идея не плохая. Действительно, если делать внешней обработкой тогда в сохраняемые настройки пихать и восстанавливать (а что там с разграничением по пользователям?). Жаль на форме не расположить интерфейсные элементы (хотя может и это удастся? пробовать лень 🙂 ).

    Впрочем, у нас лишь одна конфа имеет серьезный «бэк» в виде бухгалтерии, остальные на основе БСП полностью самостоятельные. Поэтому порой просто делаем решение, не обращая внимание на «обходные» механизмы.

    Что же касается именно кнопки «Заполнить», не всегда мы используем для нее. Есть формы подборов, куда мы тоже прикручиваем этот механизм, получается что подбор тоже усекается, чтобы быстрее/удобнее/веселее. Короче, как и писал, механизм оправдал себя, пользователи даже научились как-то им пользоваться.

    Reply
  4. triviumfan

    (3) Хранилище хранит настройки в разрезе пользователя.

    А коль для БП, то можно было бы и расширение выпустить — скорее всего оно пользовалось бы популярностью. Конторки, не имеющие программиста или не желающие платить ему за написание внешней обработки заполнения ТЧ могли бы воспользоваться сей штуковиной всего за небольшую цену =)

    Reply
  5. vandalsvq

    (4) у нас версия 2.5 (не доехавшая до 3ки вторая версия). Над расширением подумаем, но пока силы нужно на другое. Спасибо за дельные предложения.

    Reply
  6. herfis

    Название статьи было бы неплохо переделать на более точно отражающее содержание

    Reply
  7. Alias

    «Необходима версия платформы не меньше, чем 8.3.11» (с) 🙂

    неужели там есть что-то такое, чего нельзя сделать,например, на той же 8.3.10?

    Reply
  8. vandalsvq

    (7) упс, если учесть что у нас 8.3.11 но в режиме совместимости то уверен что и 8.3.6+ прокатит. Ну разве что методы Стр… надо в глобальном модуле эмулировать ))))))

    Reply
  9. Alias

    (8) смысл в том что я на своей 8.3.10 (у нас сейчас установлена такая) даже открыть конфигурацию не смог, платформа ругается.

    Reply
  10. vandalsvq

    (9) упс, вам конвертнуть или так сойдёт?

    Reply
  11. DragEugen

    Здорово, будет мне полезно! )))))

    Reply
  12. Serg O.

    это похоже на гранату…

    у нас юзеры не настолько продвинуты

    но все-равно спасибо за пост

    Reply
  13. vandalsvq

    (12) почему на гранату? ))))

    Reply
  14. rwn_driver

    А на гранату, наверное потому, что непродвинутые юзеры напоминают продвинутых обезьян, поэтому по старому анекдоту про обезьяну с гранатой…

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *