1с при изменении элемента табличной части изменить другой элемент
В этой статье будет постепенно публиковаться набор кратких шпаргалок по использованию методов языка и спосбов разработки на платформе 1С:8.2 (часть из них применима и к 8.1, но об этом упоминаться не будет).
Основные формы можно подменять формами собственной разработки, созданными в кострукторе форм.
Вопрос о событиях форм.
Ответ Существует два вида событий форм:
Вопрос Как программно изменить структуру дерева распределенной информационной базы.
Ответ Механизм распределенных информационных баз содержит программное средство конфигурирования структуры узлов распределенной базы. Для этого существует метод УстановитьГлавныйУзел() объекта ПланыОбменаМенеджер. В параметре этого метода передается ссылка на узел плана обмена распределенной информационной базы, который устанавливается главным для текущей базы. Также в этом параметре может быть передано значение Неопределено, тогда у текущей базы будет отсутствовать главный узел, т.е. она станет корневым узлом.
Пример:
При этом будут удалены все записи регистрации изменений конфигурации Узла2, относящиеся к Узлу2, передача изменений конфигурации будет возможна теперь только от Узла2 к Узлу1. Записи регистрации изменения данных удалены не будут, т.к. передача данных будет по-прежнему возможна между этими узлами.
Создание распределенной информационной базы из баз с одинаковой конфигурацией:
Вопрос Можно ли из встроенного языка менять список выбора, который генеририруется платформой автоматически в автогенерируемых формах.
Ответ Да, можно. Для этого используется обработчик события Обработка получения данных выбора, модуль которого располагается в модуле менеджера объекта. Например, в модуле менеджера справочника, когда в поле ввода подбирается один из элементов этого справочника.
Вопрос Примеры программного кода обработки констант. Как изменить несколько констант подряд. Как вывести значения всех констант, существующих в конфигурации.
Ответ
При этом особенности внутренней реализации объекта КонстантыНабор таковы, что при записи набора констант будут вызваны для каждой константы, входящей в записываемый набор, обработчики событий: ОбработкаПроверкиЗаполнения(), ПередЗаписью() и ПриЗаписи() модуля менеджера значения константы (если они там определены).
===
Вопрос Примеры программного кода работы со справочниками (аналогично с планами видов характеристик, с планами счетов, с планами видов расчета и с планами обмена).
Ответ
Вопрос Примеры программного кода обработки документов.
Ответ
Вопрос Примеры программного кода работы с перечислениями.
Ответ
Вопрос Примеры программного кода работы с регистрами сведений.
Ответ
Пример модуля проведения по этой схеме:
Вопрос В табличной части документа есть реквизит сумма. Требуется вывести итог в шапку документа. Как это лучше сделать?
Ответ Подсчет итога по графе «Сумма» и заполнение реквизита шапки этим результатом лучше сделать в МодулеДокумента в процедуре-событии «Перед записью»:
Вопрос Как в запросе осуществить выборку остатков и оборотов регистра накопления за заданный период, включая последнюю секунду, когда период задан параметрами виртуальной таблицы.
Ответ Особенность виртуальной таблицы регистра накопления такова, что когда конец выборки задается значением вида 12.13.2011 23:59:59 (т.е. конец дня), то последняя секунда дня не попадает в выборку. А если указать 12.13.2011 23:59:59 + 1 (т.е. добавить секунду), то в выборку попадут данные следующего дня, что тоже не правильно. Чтобы этого не происходило, дату окончания нужно задавать, используя метод «Граница». Пример:
Вопрос На какие данные можно опираться при проведении документов и на какие нельзя? В частности, в каком случае можно опираться на валюту, указанную в реквизите справочника договоров контрагента при проведении документа.
Ответ При проведении документа нужно следить за тем, чтобы выполняемые им движения были стабильно воспроизводимыми. Нельзя допускать ситуации, когда документ при проведении определяет, например, валюту как рубль, затем пользователь изменяет в договоре с контрагентом валюту на другую, и при повторном проведении документа валюта определяется в движениях уже как другая.
Документ в своих движениях может опираться на:
- свои реквизиты;
- значения данных, сконфигурированные таким образом, что они не могут быть потом независимо от этого документа изменены на другие;
- данные регистров, записи которых подчинены регистраторам.
Допустим, в документе есть реквизит «Договор». Для выполнения движений, предположим, требуется узнать валюту договора, т.е. валюта – это реквизит договора с контрагентом. И пусть договор – это элемент справочника «Договоры», подчиненного справочнику «Контрагенты». В таком случае при проведении документа мы можем использовать валюту из договора только в том случае, если конфигурированием мы добились того, что пользователь после записи в базу данных нового договора уже не может поменять в нем валюту. Такой запрет на изменение лучше всего разместить в предопределенной процедуре-событии модуля объекта справочника договоров «ПередЗаписью» (тогда при любом из возможных вариантов модификации этого справочника будет осуществляться соответствующая проверка):
Исторически сложилось так, что обработка изменения данных, связанных с реквизитами формы обрабатывалась в обработчиках событий этих реквизитов. Так было в 77, так до сих пор пишется код типовых конфигураций. Однако в 80 появился метод ПодключитьОбработчикИзмененияДанных, с помощью которого код изменений можно писать более прозрачно.
Рассмотрим простейший пример: пусть у документа есть реквизиты "Валюта","Курс","Кратность","Контрагент","Договор","Дата".
При изменении реквизита "Валюта" нужно установить курс и кратность валюты на дату "Дата".
При изменении реквизита "Контрагент" нужно установить в реквизит "Договор" основной договор контрагента.
Классическая схема написания обработчиков событий формы будет такая:
Однако у приведенной схемы есть недостаток.
Допустим, пользователь создал новый документ и в него подставился контрагент по умолчанию.
По идее мы должны смоделировать в этой ситуации интерактивный выбор контрагента, чтобы проставился договор или скопировать код процедуры Реквизит_Контрагент_ПриИзменении.
Это можно сделать так:
[1с]
Выполнить(""+ПолучитьДействие(ЭлементыФормы.Контрагент,"ПриИзменении")+"(ЭлементыФормы.Контрагент)");
[/1с]
Или так:
[1с]
Реквизит_Контрагент_ПриИзменении();
[/1с]
Но хочется большей универсальности чтобы не приходилось дублировать код.
Добиться этого можно другой схемой:
[1с]
Процедура ПриОткрытии()
…
//Назначаем всем данным формы обработчик ИзменениеДанных
Для Каждого Эл из ЭлементыФормы Цикл
Попытка
ПодключитьОбработчикИзмененияДанных(Эл.Данные, "ИзменениеДанных");
Исключение
КонецПопытки;
КонецЦикла;
Процедура ОтображениеДанных(Реквизит)
Если Реквизит="Договор" ИЛИ Реквизит="Контрагент" ИЛИ Реквизит="*" Тогда
ЭлементыФормы.кнВзаиморасчеты.Доступность=Пусто(Договор) Или Пусто(Контрагент);
КонецЕсли;
КонецПроцедуры
Процедура ИзменениеДанных(Реквизит)
Если Реквизит="Контрагент" Тогда
Договор=ПолучитьОсновнойДоговорПоКонтрагенту(Контрагент);
ИначеЕсли Реквизит="Валюта" Тогда
Курс=ПолучитьКурсПоВалюте(Валюта);
Кратность=ПолучитьКратностьПоВалюте(Валюта);
КонецЕсли;
ОтображениеДанных(Реквизит);
КонецПроцедуры
[/1с]
Конечно, было бы идеально, если подобные цепочки событий можно было описывать в модуле объекта, аналогично Delpy с их Property Get, Property Set (события по установке/чтению свойств объекта) но пока еще это не реализовано в 80.
А зачем нужен вызов с реквизитом "*"?
Этот вызов происходит при открытии формы и предназначен для правильного отображения статуса объектов.
Например, по задаче требуется, чтобы если был выбран договор и контрагент, то была доступна кнопка "кнВзаиморасчеты". Понятно, что контролировать доступность (отображение) этой кнопки нужно только при открытии формы и при изменении контрагента или договора. При открытии формы вызывается изменение данных всей формы (Реквизит "*"), в остальных случаях вызывается изменение каждого конкретного реквизита.
Кстати, заметим. В начале договор и контрагент пусты.
Пользователь вызывает договор. Пользователь вводит контрагента, вызывается событие ИзменениеДанных("Контрагент"), после чего проставляется договор и вызывается событие ИзменениеДанных("Договор"), после этого вызывается ОтображениеДанных("Договор"), которое делает кнопку "кнВзаиморасчеты" доступной и еще раз ОтображениеДанных("Контрагент"), которое оставляет кнопку доступной.
Как видно, при такой схеме обработки событий можно очень экономно писать код по обновлению отображения формы в зависимости от данных объекта, сравните с кодом, который вы обычно пишите в ОбновленииОтображения и почуствуйте разницу.
Однако в бочке меда есть ложка дегтя - все вышесказанное не работает для таблиц значения и табличных частей. Обработкик подключить можно, но он не вызывается при изменениях. Это очень печально и надеюсь, в будущих версиях платформы будет исправлено.
Особенности редактирования колонок табличного поля
Для уведомления о начале или окончании редактирования строки в табличном поле предназначены два события : ПередНачаломИзменения() и ПередОкончаниемРедактирования() .
Событие ПередНачаломИзменения() возникает перед началом интерактивного изменения строки табличного поля, т.е. при входе в редактирование при нажатии клавиши Enter или двойном щелчке левой кнопки мыши, а также при выполнении команды " Изменить " . Обработчик данного события имеет параметр Отказ , позволяющий отменить редактирование строки табличного поля. Важной особенностью данного события является то, что обработчик данного события вызывается только при начале редактирования существующей строки, а при добавлении новой строки не вызывается. Другой важной особенностью является то, что данное событие указывает именно на начало изменения строки табличного поля в целом, а не какого-либо значения в ячейке строки табличного поля. Поэтому при переходе с одной колонки табличного поля, находящегося в состоянии редактирования, на другую обработчик данного события не вызывается.
Событие ПередОкончаниемРедактирования () возникает перед окончанием редактирования строки, т.е. при нажатии клавиши Enter , выполнении команды " Закончить редактирование " или при щелчке мышью в другую строку табличного поля. Обработчик данного события имеет параметры НоваяСтрока , ОтменаРедактирования и Отказ . Параметр НоваяСтрока указывает, что заканчивается редактирование добавленной строки. Параметр ОтменаРедактирования указывает причину, по которой происходит окончание редактирования строки. Если значение данного параметра равно Истина , то происходит отмена редактирования в результате нажатия клавиши Esc . Наконец, параметр Отказ позволяет отменить окончание редактирования. Важной особенностью данного события является то, что обработчик данного события вызывается только при окончании редактирования строки и не вызывается при переходе от одной колонки табличного поля к другой.
Если же необходимо отслеживать изменение данных в ячейке строки табличного поля, находящегося в состоянии редактирования, то можно воспользоваться событием ПриИзменении() элемента управления, связанного с редактируемой ячейкой. Обработчик данного события вызывается после изменения значения в элементе управления при переходе от одной редактируемой ячейки табличного поля к другой.
Табличные части позволяют хранить неограниченное количество структурированной информации, принадлежащей одному объекту.
Рассмотрим некоторые приемы работы с табличными частями.
Как обойти табличную часть
Для обхода табличной части можно использовать цикл Для каждого
Для каждого Строка из ТабличнаяЧасть Цикл
На каждой итерации в переменную Строка передается очередная строка табличной части. Значения реквизитов строки можно получить выражением Строка.ИмяРеквизита.
Как получить и обойти выделенные строки табличной части
Для вывода информации из табличной части объекта служит элемент формы Табличное поле. Для включения возможности выделения нескольких строк на табличном поле нужно установить значение Множественный у его свойства Режим выделения.
Для получения перечня выделенных строк используется следующий код:
ВыделенныеСтроки = ЭлементыФормы . ИмяТабличногоПоля . ВыделенныеСтроки ;Для того чтобы обойти выделенные строки используется цикл Для каждого:
ВыделенныеСтроки = ЭлементыФормы . ИмяТабличногоПоля . ВыделенныеСтроки ;
Для каждого Строка из ВыделенныеСтроки Цикл
Как программно выделить строки табличной части (табличного поля) и снять выделение
Чтобы программно снять выделение строк табличного поля:
Чтобы программно выделить все строки табличного поля:
Как очистить табличную часть
Как получить текущую строку табличной части
Для обычных форм код будет выглядеть так:
Для управляемых форм:
Как добавить новую строку в табличную часть
Добавление новой строки в конец табличной части:
Добавление новой строки в любое место табличной части (последующие строки будут сдвинуты):
НоваяСтрока . Реквизит 1 = "Значение" ;
Как программно заполнить реквизиты строки табличной части
Если нужно программно заполнить реквизиты строки табличной части, которую добавляет пользователь, необходимо использовать обработчик события табличной части ПриНачалеРедактирования.
Создаваемая обработчиком процедура имеет три параметра:
Рассмотрим пример. Допустим, нам нужно заполнить реквизит табличной части СчетУчета, в случае, когда добавляется новая строка. При редактировании существующей строки изменять счет учета не нужно.
//Если пользователь редактирует существующую строку, то ничего не делаем
Если НЕ НоваяСтрока Тогда
Возврат ;
КонецЕсли ;
//Если же строка новая, устанавливаем счет учета
ТекСтрока = Элемент . ТекущиеДанные ; //Получили текущую строку табличной части
ТекСтрока . СчетУчета = ПланыСчетов . Хозрасчетый . НужныйСчетУчета ;
КонецПроцедуры
Работа с табличной частью объектов в 1С : 13 комментариев
Сделать это можно по-разному. Цикл Для каждого, на мой взгляд, не очень подходящий вариант, т.к. будет работать слишком долго. Да и надо еще где-то список документов брать.
Спасибо!
Буду пробовать.
А может это подойдет?
Табличная часть (Tabular section)
Итог (Total)
Синтаксис:
Тип: Число; Строка.
Индекс либо имя колонки, по которой подсчитывается итог.
Возвращаемое значение:
Тип: Число; Неопределено.
Суммирует значения всех строк в указанной колонке.
Если в колонке установлен тип и он единственный, то при суммировании будет предприниматься попытка преобразования значения к типу Число.
Если колонке не присвоены типы, то в процессе суммирования будут принимать участие только значения, имеющие тип Число, значения других типов будут игнорироваться.
Если в колонке несколько типов и среди них есть тип Число, то в процессе суммирования будут принимать участие только значения, имеющие тип Число, значения других типов будут игнорироваться.
Если в колонке несколько типов и среди них нет типа Число, то результатом будет значение Неопределено.
Сервер, толстый клиент, внешнее соединение.
Пример:
Это подошло бы, если бы нужно было суммировать колонку в одном документе. А Юрию нужно суммировать колонку Стоимость всех документов.
Добрый день!
Достаточно ли будет обратиться в модуле формы к текущей строке табличной части или в модуле менеджера тоже нужно будет что-то прописать?
Не совсем понял, о чем конкретно вопрос.
Если о том, как получать и работать с текущей строкой табличной части, то в модуле менеджера ничего писать не нужно.
Здравствуйте!
Опишу вкратце ситуацию:
Из документа вызывается команда печати штрихкодов и в обработку печати передается, как я понимаю, весь контекст документа и печатаются этикетки для всех строк документа. Возможно ли в обработке печати получить информацию только о выделенных строках из этого контекста ? Прилагаю код модуля команды ПечатьЭтикеток.
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
&НаСервере
Функция Заполнялка(ДокСсылка) Экспорт
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.АвтоМасштаб = истина ;
ТабДокумент.ОтображатьСетку = Ложь;
ТабДокумент.ТолькоПросмотр = Истина;
ТабДокумент.ОтображатьЗаголовки = Ложь;
ЧтоТо = Стр.СерийныйНомер;
ПервыйМодуль.ВывестиШтрихкодДокументаВОбластьМакета(ВнешняяКомпонента,ОбластьМакета,ЧтоТо) ;
Информацию о выделенных строках вы можете получить только в модуле формы документа, причем, если мне не изменяет память, это должна быть клиентская процедура. По ссылке на документ выделенные строки получить нельзя.
Значит я на клиенте должен сформировать таблицу выделенных строк и уже ее передавать в обработку печати ?
Доброго времени суток!
Создаю обработку на обычных формах, в которой имеется несколько Табличных частей. Они в свою очередь находят отображение в Форме обработки. И если данные первых 3, меня после закрытия Формы, не интересуют, то данные последней хотелось-бы использовать в дальнейшем, пока открыта обработка. В настоящее время при закрытии Формы Табличные части очищаются. В дальнейшем, в новом сеансе работы с обработкой эти данные не нужны. Насколько я понимаю Функции сохранения Данных Табличной части обработки не существует. Табличную часть в обработке решил использовать из-за возможности сохранить структуру Данных. Как мне сохранить эти данные для использования в других окнах?
Может у Вас есть видео по данному вопросу?
Читайте также: