Разработка удобного интерфейса для конечного пользователя (см. набор инструментов разработчика для управляемых форм 1С) — одна из ключевых задач при создании прикладных решений на платформе 1С:Предприятие 8.3. Часто возникает необходимость предоставить пользователю возможность редактировать записи регистра сведений в удобном табличном виде, напоминающем работу в Excel. Начинающие разработчики часто сталкиваются с трудностями на этом пути: ячейки таблицы не редактируются, данные не сохраняются, либо платформа блокирует изменение строк.
В этой статье мы подробно разберем, как правильно реализовать вывод данных из регистра сведений в таблицу на управляемой форме, настроить ее для интерактивного изменения пользователем и корректно записать измененные данные обратно в базу данных — для этой задачи есть настройка логики управляемых форм.
Если вы попытались вывести данные регистра на форму, но при попытке дважды кликнуть по ячейке или нажать кнопку «Изменить» ничего не происходит, дело обычно в архитектурных особенностях управляемых форм 1С. Проанализируем основные причины такого поведения — в этом поможет контроль корректности ввода данных:
Произвольный), платформа 1С не знает, какой именно элемент управления (поле ввода, календарь, флажок или поле выбора ссылки) сопоставить этой ячейке. В результате редактирование блокируется.ДинамическийСписок) предназначен для быстрого и производительного вывода больших массивов данных из базы. Платформа накладывает жесткое ограничение: редактировать записи базы данных напрямую в строках динамического списка нельзя. Изменение возможно только через открытие вспомогательной формы записи. Чтобы реализовать редактирование «внутри ячеек», необходимо использовать объект ТаблицаЗначений в качестве реквизита формы.ТолькоПросмотр = Истина, пользователь не сможет внести изменения.Рассмотрим, как решить эту задачу правильно, используя объект ТаблицаЗначений на управляемой форме. Для редактирования записей в таблице также подходит редактор записей регистров в таблице.
Для того чтобы пользователь мог свободно изменять данные, нам потребуется пройти несколько последовательных этапов настройки реквизитов формы и элементов интерфейса.
Прежде всего, нам нужно создать структуру, в которой будут храниться данные на клиенте во время их редактирования:
ТаблицаДанных).ТаблицаЗначений.СправочникСсылка.Номенклатура, для колонки «Цена» — Число с нужной точностью, для колонки «Активность» — Булево).Теперь необходимо визуализировать созданную структуру данных в интерфейсе пользователя — для этого подойдёт инструменты улучшения интерфейса управляемых форм:
ТаблицаДанных в левое окно элементов формы.Таблица и подчиненные ему элементы типа Поле ввода для каждой колонки.ТаблицаДанных и настройте его свойства в палитре свойств:
ТолькоПросмотр снят.Редактировать состав строк, Вставлять строки и Удалять строки. Это заблокирует лишние кнопки на панели и предотвратит случайное добавление пустых строк.ТолькоПросмотр также выключено, а вид элемента установлен как Поле ввода.Для того чтобы загрузить актуальные данные из регистра сведений в нашу таблицу при открытии формы, напишем серверную процедуру. Мы воспользуемся запросом для получения данных, выгрузим результат в коллекцию на сервере и перенесем эти данные в реквизит формы.
Посмотрим на пример реализации кода:
&НаСервере
Процедура ЗаполнитьТаблицуДанныхНаСервере()
// Очищаем таблицу на форме перед заполнением
ТаблицаДанных.Очистить();
// Строим запрос к регистру сведений
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
| ЦеныНоменклатуры.ТипЦен КАК ТипЦен,
| ЦеныНоменклатуры.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры";
РезультатЗапроса = Запрос.Выполнить();
// Выгружаем результат запроса в обычную таблицу значений
ТаблицаРезультат = РезультатЗапроса.Выгрузить();
// Заполняем реквизит управляемой формы данными из таблицы значений
ЗначениеВРеквизитФормы(ТаблицаРезультат, "ТаблицаДанных");
КонецПроцедуры
Эту процедуру можно вызывать, например, в стандартном обработчике события формы ПриСозданииНаСервере или по нажатию специальной кнопки «Обновить».
Когда пользователь изменил ячейки таблицы на форме, эти изменения хранятся только в оперативной памяти клиента. Нам необходимо реализовать алгоритм сохранения этих данных обратно в базу данных. Существует два основных подхода: пакетное сохранение и немедленная запись при изменении строки.
Этот метод считается наиболее надежным и удобным для пользователя. Пользователь вносит все необходимые правки, а затем нажимает кнопку «Сохранить». Вся таблица обрабатывается за один сеанс связи с сервером.
Реализуем процедуру пакетного сохранения данных:
&НаСервере
Процедура ЗаписатьИзмененияВРегистрНаСервере()
// Преобразуем реквизит формы обратно в прикладной объект ТаблицаЗначений
ТаблицаОбъект = РеквизитФормыВЗначение("ТаблицаДанных");
// Обходим строки таблицы значений в цикле
Для Каждого СтрокаТЗ Из ТаблицаОбъект Цикл
// Создаем менеджер записи для обращения к конкретной записи регистра
МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
// Заполняем ключевые измерения для поиска или создания записи
МенеджерЗаписи.Номенклатура = СтрокаТЗ.Номенклатура;
МенеджерЗаписи.ТипЦен = СтрокаТЗ.ТипЦен;
// Пытаемся прочитать существующую запись из базы данных
МенеджерЗаписи.Прочитать();
// Заполняем новые или измененные ресурсы
МенеджерЗаписи.Цена = СтрокаТЗ.Цена;
Попытка
// Записываем данные с замещением существующей записи (параметр Истина)
МенеджерЗаписи.Записать(Истина);
Исключение
ВызватьИсключение "Не удалось записать строку по номенклатуре: " + СтрокаТЗ.Номенклатура;
КонецПопытки;
КонецЦикла;
// Сообщаем пользователю об успешном сохранении
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Данные успешно сохранены в регистр.");
КонецПроцедуры
Если специфика бизнес-процесса требует, чтобы изменения попадали в базу данных мгновенно после редактирования конкретной ячейки и перехода на следующую строку, мы можем использовать событие таблицы формы ПриОкончанииРедактирования.
Для этого выполните следующие действия:
ПриОкончанииРедактирования.Посмотрим на пример программного кода для построчной записи:
&НаКлиенте
Процедура ТаблицаДанныхПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
// Если пользователь отменил редактирование, ничего делать не нужно
Если ОтменаРедактирования Тогда
Возврат;
КонецЕсли;
// Получаем данные текущей отредактированной строки
ТекущаяСтрока = Элементы.ТаблицаДанных.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
// Передаем структуру данных строки на сервер для сохранения
СтруктураДанных = Новый Структура("Номенклатура, ТипЦен, Цена");
ЗаполнитьЗначенияСвойств(СтруктураДанных, ТекущаяСтрока);
ЗаписатьСтрокуРегистраНаСервере(СтруктураДанных);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ЗаписатьСтрокуРегистраНаСервере(ДанныеСтроки)
МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Номенклатура = ДанныеСтроки.Номенклатура;
МенеджерЗаписи.ТипЦен = ДанныеСтроки.ТипЦен;
МенеджерЗаписи.Прочитать();
МенеджерЗаписи.Цена = ДанныеСтроки.Price; // Обновляем ресурс
Попытка
МенеджерЗаписи.Записать(Истина);
Исключение
ЗаписьЖурналаРегистрации("Ошибка записи регистра", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка при записи строки");
КонецПопытки;
КонецПроцедуры
Обратите внимание: Данный подход создает дополнительную нагрузку на сервер 1С и базу данных при каждом переходе пользователя по строкам таблицы, поэтому использовать его стоит обдуманно.
В процессе обсуждения часто возникает дилемма: что лучше использовать для вывода данных — ТабличныйДокумент или ТаблицуЗначений? Проанализируем ключевые особенности каждого объекта:
Таблица Значений — это идеальный инструмент для работы со структурированными данными. Каждая колонка имеет жестко определенный тип. Платформа 1С берет на себя всю рутину по автоматической визуализации элементов управления: пользователю открывается календарь для выбора даты, выпадает список для перечисления или открывается форма выбора для ссылочных типов (справочники, документы). Данные легко выгружать запросом и обходить в цикле.
Табличный Документ разработан преимущественно для формирования печатных форм, отчетов и вывода неструктурированной информации. Сделать его доступным для редактирования пользователю можно, однако обрабатывать изменения в нем крайне сложно. Разработчику придется вручную отслеживать координаты измененных ячеек, преобразовывать строковый текст в нужные типы данных и сопоставлять их с измерениями регистра сведений. Используйте табличный документ для ввода данных только в крайних случаях, когда форма ввода должна иметь сложный нерегулярный вид (например, регламентированные отчеты).
Мы подробно разобрали механизм организации редактирования данных регистра сведений «как в Excel». Подведем итог основным правилам, которые гарантируют успех при реализации этой задачи:
ТаблицаЗначений.ТолькоПросмотр и Доступность как у самой таблицы, так и у колонок формы.МенеджерЗаписи для детальной построчной перезаписи данных, либо НаборЗаписей для пакетного обновления данных по определенному отбору.