1С-Предприятие 8.0. Практическое пособие разработчика

         

Создание документа ввода начальных остатков


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

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

Рассмотрим пример ввода начальных остатков регистра накопления "ОстаткиМатериалов". Для выполнения этой задачи мы создадим документ, в котором будем вручную редактировать его движения по регистру "ОстаткиМатериалов" прямо в форме документа.

Откроем конфигуратор и создадим новый объект конфигурации Документ с именем "ВводНачальныхОстатковНоменклатуры". На закладке "Движения" запретим проведение документа (поскольку сами будем формировать записи регистра), и отметим, что движения документа будут находиться в регистре накопления "ОстаткиМатериалов". После этого перейдем на закладку "Формы" и создадим основную форму документа. [477]

Раздвинем форму вниз и разместим в ней табличное поле c командной панелью. Зададим имя табличного поля "ОстаткиМатериалов" и тип значения "РегистрНакопленияНаборЗаписей.ОстаткиМатериалов":

В свойствах табличного поля укажем, что источником данных для него будут являться движения документа по регистру "ОстаткиМатериалов":


[478]

Удалим из табличного поля колонки "Регистратор" и "Активность" (они нам не понадобятся), и изменим размеры формы и расположение элементов управления:

Запустим 1С:Предприятие в режиме отладки и проверим работу нашего документа.






Введем в документ следующие данные:

Обратите внимание на то, что дата документа не совпадает с датами отдельных записей, которые мы создаем в движениях документа. [479]
Нажмем "Записать", и из формы списка документа откроем движения нашего документа в регистре "ОстаткиМатериалов" (кнопка "Перейти").
Вы видите, что записи регистра накопления в точности соответствуют тем, которые мы создали в документе:

Таким образом, мы добились поставленной цели: с одной стороны, задавая дату документа, мы можем фиксировать момент внесения изменений в записи регистра, с другой стороны – для каждой создаваемой нами записи регистра, мы можем указать индивидуальное значение поля "Период".
Теперь займемся "ужесточением" требований, предъявляемых к тому, как наш документ формирует записи регистра, и рассмотрим два типичных варианта.
Первое требование, которое мы реализуем, будет заключаться в том, что записи регистра должны формироваться той же датой, что и дата документа. Иначе говоря, синхронизируем дату движений с датой документа.
Для этого в обработчик события "Перед записью" формы документа добавим следующий текст:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
   Для Каждого ЗаписьРегистра Из Движения.ОстаткиМатериалов Цикл
       ЗаписьРегистра.Период = Дата;
   КонецЦикла;
КонецПроцедуры [480]
Снова запустим 1С:Предприятие в режиме отладки, откроем наш документ и нажмем "Записать". Открыв движения документа в регистре "ОстаткиМатериалов" увидим, что значение поля "Период" у всех записей стало равно дате документа:

Можно сказать, что мы достигли поставленной цели, но лишь в ситуации, когда запись документа выполняется интерактивными средствами.
Если программно вызвать метод Записать() у объекта нашего документа, он будет записан без участия формы документа. Это значит, что событие "При записи" формы документа вызвано не будет, и наш код обработчика не отработает.


Чтобы предусмотреть возможность синхронизации периода движений документа с датой документа и в случае программной записи объекта Документ, следует использовать обработчик события "Перед записью" объекта документ, а не формы документа. [481]
Событие "Перед записью", в случае интерактивной записи документа, сначала будет вызвано у формы документа, а затем объекта документа (смотри схему событий в раздел "Последовательность событий при записи документа из форм документа" на странице 581). Поэтому вернемся в конфигуратор удалим из модуля формы добавленный нами текст и создадим обработчик события "Перед записью" в модуле объекта документ:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
   //Определить нужно ли обновлять дату в движениях
   ОбновитьДатуДвижений = ЭтоНовый() Или Движения.ОстаткиМатериалов.Модифицированность();
   Если Не ОбновитьДатуДвижений Тогда // Проверить, что дата изменилась
       Запрос = Новый Запрос;
       Запрос.УстановитьПараметр("ТекущийДокумент", Ссылка);
       Запрос.Текст =
       "ВЫБРАТЬ
       |    ВводНачальныхОстатковНоменклатуры.Дата
       |ИЗ
       |    Документ.ВводНачальныхОстатковНоменклатуры КАК ВводНачальныхОстатковНоменклатуры
       |ГДЕ
       |    ВводНачальныхОстатковНоменклатуры.Ссылка = &ТекущийДокумент";
       Выборка = Запрос.Выполнить().Выбрать();
       Выборка.Следующий();
       ОбновитьДатуДвижений = Выборка.Дата <> Дата;
   КонецЕсли;
   //Установить всем новую дату, если нужно


   Если ОбновитьДатуДвижений Тогда
       Если Не Движения.ОстаткиМатериалов.Выбран() И Не Движения.ОстаткиМатериалов.Модифицированность() Тогда
           Движения.ОстаткиМатериалов.Прочитать();
       КонецЕсли;
       Для Каждого ЗаписьРегистра Из Движения.ОстаткиМатериалов Цикл
           ЗаписьРегистра.Период = Дата;
       КонецЦикла;
   КонецЕсли;
КонецПроцедуры
Как вы видите, в этом случае обработчик содержит больше кода за счет дополнительных проверок, которые выполняются в результат того, что возможна как интерактивная, так и программная запись объекта. [482]
Поясним содержание обработчика. Если записывается новый документ или были изменены его движения – следует обновить дату движений. В противном случае мы считываем запросом дату документа из базы данных и сравниваем ее с датой, установленной у записываемого объекта. Если даты разные – также следует обновить дату движений.
Перед установкой даты мы проверяем, был ли прочитан набор записей в свойстве "Движения" объекта и изменялся ли он. Если оба этих условия ложны – это значит, что набор записей в свойстве "Движения" объекта пуст, и это состояние не связано с его изменением. В этом случае, чтобы предотвратить ошибочное удаление записей в регистре (перезапись пустым набором записей), мы предварительно читаем движения из регистра в набор записей в свойстве "Движения". Затем, как и в предыдущем случае, устанавливаем нужную дату для всех записей этого набора. При выполнении записи объекта Документ, этот набор будет записан в регистр накопления.
Запустим 1С:Предприятие в режиме отладки и убедимся, что указав новую дату для нашего документа и записав его, мы получим движения в регистре накопления с новой датой.


В процессе записи нашего документа можно управлять не только периодом записей регистра накопления, но и значениями других полей регистра.
Например, по аналогичному принципу может быть создан документ "Операция", позволяющий вводить ручные операции в регистр бухгалтерии. При этом, вероятно, кроме управления периодом записей регистра, вам потребуется управлять значением поля "Активность" ("включать" и "выключать" проводки документа) и т.д.
В заключение следует сказать, что выбор обработчика, в котором будет размещен текст процедуры, зависит от логики работы создаваемого объекта. Если конфигурация не предусматривает программной записи объекта – можно выбрать обработчик модуля формы. Если предполагается и программная модификация объекта – следует выбирать обработчик модуля объекта.
Заметьте, что оба эти способа не исключают модификацию записей регистра через объект Регистр<...>НаборЗаписей.<имя регистра>. Поэтому, если логика конфигурации подразумевает возможность программной модификации объекта набор записей, код обработки [483] следует размещать в обработчике события набора записей. Все попытки изменить данные регистра будут сведены, в конечном счете, к записи именно набора записей. [484]



Содержание раздела