Редактирование табличной части объекта с помощью СКД


Тема не нова — похожие решения были и на 8.0. К написанию статьи меня подтолкнул коллега, т.к. я это чудом не считаю. Несколько раз я видел тонны сложнейшего, и посему нерабочего кода, целью которого было сделать нечто похожее средствами, которые для этого не предназначены. В статье дан простейший пример, показывающий, как можно применять средства СКД для редактирования сложной структуры данных, например, табличных частей документов. В частности, рассмотрена работа с набором данных типа «Объект» и событием «Обработка расшифровки»

Описание проблемы и предпосылки

Периодически приходится решать задачи удобного ввода информации пользователем по образу Excel, например, самый простой "План продаж" по месяцам, в котором горизонтально по колонкам расположены месяцы, а вертикально — некая аналитика. Раньше в типовых конфигурациях 1С данная задача не была решена вообще никак. Пользователю предлагалось заполнить обычную табличную часть вручную, добавляя строки и заполняя их датами и необходимой аналитикой. Весь ужас такого ввода объяснять не нужно. Потом разработчики отраслевых решений в "доэскадэшную" эпоху догадались использовать всю мощь макета табличного документа и в "Подрядчик строительства" от "Импульс ИВЦ" уже можно было наблюдать весьма недурное решение в блоке Бюджетирование. Но код был неуниверсальный, сложный и крайне тяжело переносился на другие похожие задачи. В данной статье я постараюсь показать, как решить эту задачу быстро, красиво и с минимальными затратами по времени. Также код, который вы напишете, используя этот пример, вы сможете легко переносить на другие свои решения.

Реализация задачи

Нам понадобится: сам объект редактирования (в данном случае табличная часть), макет СКД, компоновщик настроек компоновки данных, элемент управления "поле табличного документа", обработчик "Обработка расшифровки".

Макет СКД представляет собой соединение двух наборов данных, каждый из которых имеет тип "Наборданных-объект":

 

 

Настройки вывода просты и примитивны — это обычная таблица с итогами:

 

В форме необходимо разместить следующие реквизиты:


В 

Основная идея:

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

Данный код позволяет определить по какой именно ячейке кликнул пользователь. Далее, зная значение Номенклатуры и Периода можно найти соответствующую строку в табличной части и присвоить в ней реквизиту "Сумма" нужное значение, после можно программно нажать на кнопку "Обновить".

 

СтандартнаяОбработка = Ложь;

ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаСКД));

СтруктураРасшифровки = Новый Структура("Номенклатура, Период");

НастройкиКомпоновкиДанных = ОбработкаРасшифровки.Расшифровать(Расшифровка, Новый ПолеКомпоновкиДанных("Номенклатура"));

ЭлементыОтбора = НастройкиКомпоновкиДанных.Отбор.Элементы;

Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл

Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура") Тогда
СтруктураРасшифровки.Номенклатура  = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;

Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Период") Тогда
СтруктураРасшифровки.Период  = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;

КонецЦикла;

 

Производительность

Существует 2 способа непосредственного ввода значения при двойном клике по ячейки:

1) Через диалоговое окно методами ВвестиЗначение() или ВвестиЧисло()

— этот способ применен в данном примере.

Преимущества: не усложняет код, высокая производительность.

Недостатки: вылетает дополнительное окно ввода.

При таком способе ввода в каждой ячейке, как и при формировании обычного отчета на СКД, содержится лишь некий объект типа "ИдентификаторРасшифровкиКомпоновкиДанных", который по сути представляет собой число.

2) Непосредственно в ячейку, как в Excel.

Данный способ с применением СКД можно увидеть в ERP 2.0.

Преимущества: очень красиво, у неискушенных вызывает мгновенный вау-эффект, окон не вылетает.

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

Что еще?

1) Никто не запрещает размещать на форме стандарнтые настроки компоновщика настроек.

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

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

4) Можно и нужно использовать всю мощь СКД и возможностей условного оформления.

27 Comments

  1. json

    Есть несколько вопросов:

    1. При редактировании тч необходимо иметь возможность добавлять и удалять строки. В данной схеме это предусмотрено?

    2. При обновлении курсор в табличном документе позиционируется на верхний левый угол. С этим что-нибудь делаете?

    3. Обновляете ли итоги в подвале при вводе числовых значений?

    Reply
  2. Hatson

    (1) yurii_host,

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

    2) Это не так. Курсор остается на той ячейке, которую редактировали.

    3) Итоги рассчитывает СКД. Я просто вызываю процедуру вывода результата в табличный документ после каждого ввода значения.

    Reply
  3. German_Tagil

    надо посмотреть

    Reply
  4. fomix

    К чему все это? Если только для какого-то извращения с расчетами в ТЧ, то понятно. А так… Может не так понял автора…

    Reply
  5. Lukich66

    «как можно применять средства СКД для редактирования сложной структуры данных, например, табличных частей документов. »

    Я увидел только редактирование табличного документа, а не табличной части(Товары,Услуги) документа

    Reply
  6. Diego_Iv

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

    Хотелось чтобы суммы можно было вводить по колонкам, как в экселе. Причем количество периодов в документе могло быть неограниченным (7 дней недели, 30 дней месяца или все 365 дней года).

    Предложенное решение с табличным документом, аналогичное упомянутому «Подрядчику строительства» заказчику не понравилось. Табличное поле документа не похожа на обычное в других документах 1С, не работают автоподборы и т.д.

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

    Reply
  7. Трактор

    >> Ячеек в поле табличного документа может быть несколько тысяч, т.е. несколько тысяч полей ввода

    Я эту проблему решил так. Добавляю поле ввода в ячейку в момент активизации ячейки. Тормозов практически нет.

    Reply
  8. drmaxart

    Самое очевидное применение — удобное редактирование подчиненных по ключам связи табличных частей

    Reply
  9. Lancelot-2M

    Я такую тему делал) С копированием и добавлением строк и даже прямоугольных областей — вау-эффект был у моего начальника, а юзеры не пользуются)))

    Reply
  10. Hatson

    (6) Diego_Iv, приложенные картинки не открываются. Может я не туда тыкаю?

    Reply
  11. gubanoff

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

    Reply
  12. Hatson

    (10) gubanoff, да, такими решениями кишат старые УТ. Всё здорово, только много говнокода и если пользователь попросит группировочки с итогами, условное оформление и т.д., то «добрый вечер».

    Reply
  13. Hatson

    (9) Lancelot-2M, надо было сразу статью зафигачить )

    Reply
  14. Hatson

    (7) Трактор, понравилась идея. Пример кода можешь кинуть?

    Reply
  15. vasilev2015

    (4) fomix, если ищете извращений, посмотрите типовой документ «табель» в ЗУП. Там бы это пригодилось. )))

    Reply
  16. Diego_Iv

    (11) ПКМ — Открыть изображение.

    (10) Какие «группировочки и условное оформление» в табличном поле документа? Все эти украшательства решаются печатными формами и отчетами

    Reply
  17. Vlad_2008

    Во-во, а уж если нужны группировочки, то для этого есть Дерево и УО (в УФ)

    Reply
  18. simon_simon

    Немного не по теме статьи, но не так давно пришлось делать внешнюю печатную форму с использованием СКД. Данная печатная форма разработана для документа «Пересчет товаров» Розница, редакция 2.1 (2.1.9.20) . Не знаю как у кого, но у меня возникли проблемы найти пример в сети. Везде денег хотели.

    По сути печатной формы: По заданию пользователей необходимо было сделать печатную форму с группировками по виду номенклатуры. Внутри группировок непосредственно сами номенклатурные позиции.

    Reply
  19. monkbest

    В ЗУП 3.0 так реадктируется документ Табель при включенной функциАнальной опции наличия территорий выполнения работ. В этом случае там помимо 31 колонки на каждый день для ввода буквы и часов надо еще рисовать поля для указания периоды пребывания на удаленной территории. Т.е. информация мягко говоря не укалдывающаяся в ТЧ из за разнородности.

    Второе ТабДок поддрежывает отображение тысяч строк и сотен колонок, а табличная часть в УФ умирает, а в веб-клиенте вообще падает со свякими ошибками javaSript`а

    Reply
  20. Diego_Iv

    Попиарюсь…

    Описанное в (6) выложил в виде отдельной публикации

    http://infostart.ru/public/553075/

    Reply
  21. user702069_savel777v2

    (12) Присоединяюсь…. Изначально сделал на ТЗ по найденной идее http://infostart.ru/public/547892/

    Всё бы хорошо… но попросили Итоги по ТЗ…. вот тут я и встрял.. Потому оказалось проще переписать всё на СКД, как Hatson и предложил

    немного возни с обработчиками, зато потом в доработке — сказка…. Внешний вид правил многократно, что на ТЗ вылилось бы в килотонны кода.

    А на счет обработчиков сначала сделал в виде ВвестиЗначение, а завершилось вообще все на ФормеВвода…

    Потому Автору — большая благодарность за идею!

    Reply
  22. lopatin

    Есть пример редактирования прямо в ячейке? Без вывода окна?

    Reply
  23. sailor-cat

    (22)при активизации области:

    Область = ТабличныйДокумент.ТекущаяОбласть;
    Область.СодержитЗначение = Истина;
    Область.ТипЗначения = ОписаниеТипов;
    Область.УстановитьЭлементУправления(Тип(«ПолеВвода»));

    Но вот как назначить элементу обработчики события, пока не могу сообразить.

    Reply
  24. lopatin
    Reply
  25. lopatin

    (23) Соответственно, чтобы отловить момент изменения значения и записать его в нужное место, определил событие табличного поля на форме — ПриИзмененииСодержимогоОбласти, проверяю расшифровку и если область та что мне нужна записываю значение:

    &НаКлиенте
    Процедура ПредставлениеДанныхОтчетаПриИзмененииСодержимогоОбласти(Элемент, Область)
    ПредставлениеДанныхОтчетаПриИзмененииСодержимогоОбластиНаСер­вере(Область.Расшифровка, Область.Значение);
    КонецПроцедуры
    
    &НаСервере
    Процедура ПредставлениеДанныхОтчетаПриИзмененииСодержимогоОбластиНаСер­вере(Расшифровка, Значение)
    Если НЕ Расшифровка = Неопределено Тогда
    Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
    ЗначенияРасшифровки = ВыводФинансовыхОтчетов.ПолучитьВсеЗначенияРасшифровки(Данные.Элементы[Расшифровка]);
    ЗначенияГруппировок = ВыводФинансовыхОтчетов.ПолучитьВсеЗначенияГруппировок(Данные, Расшифровка, «Значение», Новый Структура(«Показатель,Период»));
    Если ЗначенияРасшифровки.Свойство(«Значение») Тогда
    ЗаписатьЗначениеПоказателя(ЗначенияГруппировок.Показатель, Значение);
    КонецЕсли;
    КонецЕсли;
    КонецПроцедуры
    

    Показать

    Reply
  26. sailor-cat

    (25) Согласен, можно и так, но:

    1. Как отмечалось выше, добавлять элементы при компоновке результата может быть весьма «дорого».

    2. Меня интересовали обработчики других событий, например «Начало выбора». Поэтому и пытался все перенести на форму.

    Reply
  27. Hatson

    Добавил кнопку «Добавить строку» и обработка подорожала ))

    Reply

Leave a Comment

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