Описание проблемы и предпосылки
Периодически приходится решать задачи удобного ввода информации пользователем по образу Excel, например, самый простой "План продаж" по месяцам, в котором горизонтально по колонкам расположены месяцы, а вертикально — некая аналитика. Раньше в типовых конфигурациях 1С данная задача не была решена вообще никак. Пользователю предлагалось заполнить обычную табличную часть вручную, добавляя строки и заполняя их датами и необходимой аналитикой. Весь ужас такого ввода объяснять не нужно. Потом разработчики отраслевых решений в "доэскадэшную" эпоху догадались использовать всю мощь макета табличного документа и в "Подрядчик строительства" от "Импульс ИВЦ" уже можно было наблюдать весьма недурное решение в блоке Бюджетирование. Но код был неуниверсальный, сложный и крайне тяжело переносился на другие похожие задачи. В данной статье я постараюсь показать, как решить эту задачу быстро, красиво и с минимальными затратами по времени. Также код, который вы напишете, используя этот пример, вы сможете легко переносить на другие свои решения.
Реализация задачи
Нам понадобится: сам объект редактирования (в данном случае табличная часть), макет СКД, компоновщик настроек компоновки данных, элемент управления "поле табличного документа", обработчик "Обработка расшифровки".
Макет СКД представляет собой соединение двух наборов данных, каждый из которых имеет тип "Наборданных-объект":
Настройки вывода просты и примитивны — это обычная таблица с итогами:
В форме необходимо разместить следующие реквизиты:
В
Основная идея:
В обработчике расшифровки должен быть размещен отказ от стандартной обработки, а также описание набора действий, которые необходимо совершить, когда пользователь кликает по ячейке двойным кликом.
Данный код позволяет определить по какой именно ячейке кликнул пользователь. Далее, зная значение Номенклатуры и Периода можно найти соответствующую строку в табличной части и присвоить в ней реквизиту "Сумма" нужное значение, после можно программно нажать на кнопку "Обновить".
СтандартнаяОбработка = Ложь;
ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаСКД));
СтруктураРасшифровки = Новый Структура("Номенклатура, Период");
НастройкиКомпоновкиДанных = ОбработкаРасшифровки.Расшифровать(Расшифровка, Новый ПолеКомпоновкиДанных("Номенклатура"));
ЭлементыОтбора = НастройкиКомпоновкиДанных.Отбор.Элементы;
Для Каждого ЭлементОтбора Из ЭлементыОтбора Цикл
Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура") Тогда
СтруктураРасшифровки.Номенклатура = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Период") Тогда
СтруктураРасшифровки.Период = ЭлементОтбора.ПравоеЗначение;
КонецЕсли;
КонецЦикла;
Производительность
Существует 2 способа непосредственного ввода значения при двойном клике по ячейки:
1) Через диалоговое окно методами ВвестиЗначение() или ВвестиЧисло()
— этот способ применен в данном примере.
Преимущества: не усложняет код, высокая производительность.
Недостатки: вылетает дополнительное окно ввода.
При таком способе ввода в каждой ячейке, как и при формировании обычного отчета на СКД, содержится лишь некий объект типа "ИдентификаторРасшифровкиКомпоновкиДанных", который по сути представляет собой число.
2) Непосредственно в ячейку, как в Excel.
Данный способ с применением СКД можно увидеть в ERP 2.0.
Преимущества: очень красиво, у неискушенных вызывает мгновенный вау-эффект, окон не вылетает.
Недостатки: низкая производительность, усложняет код. Нужно понимать, что при таком способе ввода в каждую ячейку придется помещать элемент управления "Поле ввода". Ячеек в поле табличного документа может быть несколько тысяч, т.е. несколько тысяч полей ввода. Вывод этого всего в поле табличного документа не будет быстрым даже в толстом клиенте.
Что еще?
1) Никто не запрещает размещать на форме стандарнтые настроки компоновщика настроек.
2) Можно добавлять в схему СКД любую другую информацию (с помощью других наборов данных), которая не содержится в табличной части редактируемого объекта, но которая необходима для принятия решения при вводе данных (например свойства номенклатуры).
3) Группировка данных в таблице также может быть сколь угодно сложной, в зависимости от решаемой задачи.
4) Можно и нужно использовать всю мощь СКД и возможностей условного оформления.
Есть несколько вопросов:
1. При редактировании тч необходимо иметь возможность добавлять и удалять строки. В данной схеме это предусмотрено?
2. При обновлении курсор в табличном документе позиционируется на верхний левый угол. С этим что-нибудь делаете?
3. Обновляете ли итоги в подвале при вводе числовых значений?
(1) yurii_host,
1) Добавлять и удалять строки можно. Для этого придется реализовать простую кнопку. В данном примере такой кнопки нет, чтобы не захламлять код.
2) Это не так. Курсор остается на той ячейке, которую редактировали.
3) Итоги рассчитывает СКД. Я просто вызываю процедуру вывода результата в табличный документ после каждого ввода значения.
надо посмотреть
К чему все это? Если только для какого-то извращения с расчетами в ТЧ, то понятно. А так… Может не так понял автора…
«как можно применять средства СКД для редактирования сложной структуры данных, например, табличных частей документов. »
Я увидел только редактирование табличного документа, а не табличной части(Товары,Услуги) документа
При внедрении блока бюджетирования тоже встречался с подобной задачей. В табличную часть документа (бюджетная операция) необходимо было вводить следующие данные по периодам: Статья бюджета — Проект — Контрагент — Договор — Номенклатура — Сумма операции.
Хотелось чтобы суммы можно было вводить по колонкам, как в экселе. Причем количество периодов в документе могло быть неограниченным (7 дней недели, 30 дней месяца или все 365 дней года).
Предложенное решение с табличным документом, аналогичное упомянутому «Подрядчику строительства» заказчику не понравилось. Табличное поле документа не похожа на обычное в других документах 1С, не работают автоподборы и т.д.
Удалось решить так. По табличной части документа строил таблицу значений с нужным количеством колонок для каждого периода и эту ТЗ выводил в табличное поле документа.
>> Ячеек в поле табличного документа может быть несколько тысяч, т.е. несколько тысяч полей ввода
Я эту проблему решил так. Добавляю поле ввода в ячейку в момент активизации ячейки. Тормозов практически нет.
Самое очевидное применение — удобное редактирование подчиненных по ключам связи табличных частей
Я такую тему делал) С копированием и добавлением строк и даже прямоугольных областей — вау-эффект был у моего начальника, а юзеры не пользуются)))
(6) Diego_Iv, приложенные картинки не открываются. Может я не туда тыкаю?
Создаем на форме таблицу значений (ТЗ), которую программно формируем как хотим. Нужно добавить только две процедуры — при открытии документа загрузить в эту ТЗ данные из ТЧ, при записи документа сохранить данные из ТЧ в ТЗ. Не очень сложная задача. В результате пользователь работает с привычной ему ТЧ (хотя на самом деле это ТЗ на форме, но визуально пользователь разницы не видит). Плюс в ТЗ можно добавлять обработчики событий изменения реквизитов, итоги по колонкам, подбор при вводе значений и т.п., т.е. будет полный аналог ТЧ.
(10) gubanoff, да, такими решениями кишат старые УТ. Всё здорово, только много говнокода и если пользователь попросит группировочки с итогами, условное оформление и т.д., то «добрый вечер».
(9) Lancelot-2M, надо было сразу статью зафигачить )
(7) Трактор, понравилась идея. Пример кода можешь кинуть?
(4) fomix, если ищете извращений, посмотрите типовой документ «табель» в ЗУП. Там бы это пригодилось. )))
(11) ПКМ — Открыть изображение.
(10) Какие «группировочки и условное оформление» в табличном поле документа? Все эти украшательства решаются печатными формами и отчетами
Во-во, а уж если нужны группировочки, то для этого есть Дерево и УО (в УФ)
Немного не по теме статьи, но не так давно пришлось делать внешнюю печатную форму с использованием СКД. Данная печатная форма разработана для документа «Пересчет товаров» Розница, редакция 2.1 (2.1.9.20) . Не знаю как у кого, но у меня возникли проблемы найти пример в сети. Везде денег хотели.
По сути печатной формы: По заданию пользователей необходимо было сделать печатную форму с группировками по виду номенклатуры. Внутри группировок непосредственно сами номенклатурные позиции.
В ЗУП 3.0 так реадктируется документ Табель при включенной функциАнальной опции наличия территорий выполнения работ. В этом случае там помимо 31 колонки на каждый день для ввода буквы и часов надо еще рисовать поля для указания периоды пребывания на удаленной территории. Т.е. информация мягко говоря не укалдывающаяся в ТЧ из за разнородности.
Второе ТабДок поддрежывает отображение тысяч строк и сотен колонок, а табличная часть в УФ умирает, а в веб-клиенте вообще падает со свякими ошибками javaSript`а
Попиарюсь…
http://infostart.ru/public/553075/
Описанное в (6) выложил в виде отдельной публикации
(12) Присоединяюсь…. Изначально сделал на ТЗ по найденной идееhttp://infostart.ru/public/547892/
Всё бы хорошо… но попросили Итоги по ТЗ…. вот тут я и встрял.. Потому оказалось проще переписать всё на СКД, как Hatson и предложил
немного возни с обработчиками, зато потом в доработке — сказка…. Внешний вид правил многократно, что на ТЗ вылилось бы в килотонны кода.
А на счет обработчиков сначала сделал в виде ВвестиЗначение, а завершилось вообще все на ФормеВвода…
Потому Автору — большая благодарность за идею!
Есть пример редактирования прямо в ячейке? Без вывода окна?
(22)при активизации области:
Но вот как назначить элементу обработчики события, пока не могу сообразить.
(23) Соответственно, чтобы отловить момент изменения значения и записать его в нужное место, определил событие табличного поля на форме — ПриИзмененииСодержимогоОбласти, проверяю расшифровку и если область та что мне нужна записываю значение:
Показать
(25) Согласен, можно и так, но:
1. Как отмечалось выше, добавлять элементы при компоновке результата может быть весьма «дорого».
2. Меня интересовали обработчики других событий, например «Начало выбора». Поэтому и пытался все перенести на форму.
Добавил кнопку «Добавить строку» и обработка подорожала ))