Афина. Программное сохранение и изменение информации в справочниках К содержанию
   

В основном все записи справочников создаются и модифицируются пользователями. Но часто требуется и программное создание или изменение значений записей справочника. Здесь речь пойдет о том как это делается.

Переменные типа справочник, которые мы объявляем в программах предназначены для того чтобы "хранить" ссылки на записи справочника.
Если переменная объявляется так:

переменные
  справочник(Организации) спрОрг;

то такая переменная может указывать на какую-либо запись из справочника "Организации", т.е. ссылаться на запись о конкретной организации.

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

"Зарядить" переменную нужной записью можно различными путями (зависит от целей, для которых это делается).
Например, перебором, что называется "в лоб":

пока СледующееЗначение(спрОрг) делать
  если спрОрг.Наименование = "ООО Приемник" то прервать конец;
конец

если организация с таким именем есть в записях, то после прерывания цикла (оператор "прервать") спрОрг будет указывать на запись с найденной организацией. Если организации с таким именем нет, то проверка через функцию ПустоеЗначение(спрОрг) вернет "Да", означающее что в спрОрг ссылки на организацию нет.

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

если НайтиЗначение(Документ := спрОрг, Наименование =
"ООО Приемник") то
  ... !запись найдена и в переменной "спрОрг" содержится указатель на нужную запись
иначе
  ... !запись не найдена
конец

Можно получить нужную запись справочника в переменной через глобальные константы, если есть константа (см. константы), содержащая запись этой организации простым присвоением:
  спрОрг := _констОООПриемник;

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

Если в нашем примере переменная спрОрг содержит указатель на организацию, то в программе мы можем получить значения полей именно этой организации.

Эти значения могут применяться для чего угодно, но только для чтения информации из полей. То есть для изменения значений полей переменная не предназначена.
Например, конструкция

  Наим := спрОрг.Наименование;
присвоение локальной переменной "Наим" значения поля Наименование корректна и будет работать, а конструкция
  спрОрг.Наименование := "Приемник ООО";
исправление наименования организации напрямую сгенерирует ошибку при компиляции кода программы, где эта конструкция применяется.

Таким образом, для того чтобы сделать исправления значений полей любого справочника необходимо:
- иметь переменную этого справочника;
- необходимо чтобы переменная указывала на ту запись, значения полей которой мы меняем;
- применить специальную функцию ИзменитьЗначение.

Эта функция может иметь переменное количество именованных параметров. Первый параметр предопределен (должен присутствовать всегда) и называется "Документ" и ему присваивается переменная типа справочника, которая уже должна содержать ссылку на исправляемую запись.
Количество остальных параметров может быть различное, в которых перечисляются имена полей этого справочника и присвоение им значений в форме <имя поля> := <значение>.

Самый простой пример. Исправим наименование организации, которая в справочнике Организации называется "ООО Приемник".
Вначале найдем запись, которая соответствует этой организации в справочнике. Затем исправим наименование. Все это сделаем в некоей функции другого справочника.

функция ХХХХХХ
переменные справочник(Организации) сОрг;
начало
  если НайтиЗначение(Документ := сОрг, Наименование = "ООО Приемник") то
    ИзменитьЗначение(Документ := сОрг, Наименование := "Приемник ООО");
  конец;
конец

Несколько уточнений:
В функции передаются только те параметры и их значения, которые надо менять (остальные значения в записи сохраняются как есть.
Если надо изменить значения колонок таблицы, то предварительно объявляются локальные колонки соответствующего типам колонок таблицы; добавляются нужное количество элементов в эти колонки и заполняются значениями; в функцию передаются параметры в форме:
 <таблица.колонка > := <локальная колонка со значениями>.

Для добавления новой записи в справочник:
- необходимо иметь переменную этого справочника;
- применить специальную функцию ЗаписатьЗначение.

В примере рассмотрим добавление новой записи в справочник "Счета-фактуры" из справочника, который хранит расходные накладные. В справочнике "Счета-фактуры" помимо номера и покупателя есть таблица, в которой колонки содержать: наименование товара, количество, сумма без НДС, ставка НДС, сумма НДС и сумма с НДС (таблицу назовем "ТСФ").

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

функция НажатаКнопкаСФ
переменные
  справочник([Счета-фактуры] спрСФ;
  колонка(справочник(Товары)) кТов;
  колонка(число) кЦена, кСуммаБезНДС, кСтавка, кСуммаНДС;
  число А;
начало
  !предполагается, что перед выполнением этой функции накладная уже сформирована и в ней
  !есть таблица с заполненными пользователем колонками: Наименованием товара,
  !количеством и суммой с НДС (таблица называется "Т").


  !Добавляем в локальные колонки столько элементов сколько их содержится
  !в таблице накладной.

  ВстЭлемент(кЦена,, количествоСтрок(Т)):
  ВстЭлемент(кСуммаНДС,, количествоСтрок(Т)):
  ВстЭлемент(кСтавка,, количествоСтрок(Т)):
  ВстЭлемент(кСуммаБезНДС,, количествоСтрок(Т)):

  !рассчитываем и заполняем значения локальных колонок
  цикл А от 1 до КоличествоСтрок(Т) делать
    кСуммаНДС(А) := (Т.Сумма(А) / (_СтавкаНДС + 100)) * _СтавкаНДС;
    кСуммаБезНДС(А) := Т.Сумма(А) - кСуммаНДС(А);
    кСтавка(А) := _СтавкаНДС;
    кЦена(А) := Т.Сумма(А) / Т.Кол(А);
  конец;

  ЗаписатьЗначение(Документ := спрСФ, Привязка := Да,
      Номер := Номер, Покупатель := Покупатель,
      ТСФ.Наименование := Т.Наименование, ТСФ.Колич := Т.Кол,
      ТСФ.СуммаБезНДС := кСуммаБезНДС, ТСФ.СуммаНДС := кСуммаНДС,
      ТСФ.СтавкаНДС := кСтавка, ТСФ.Сумма := Т.Сумма, ТСФ.Цена := Т.Цена)

конец

Примечания.
- Так как в функции ЗаписатьЗначение (или ИзменитьЗначение) применяются именованные параметры, то последовательность их появления в списке параметров значения не имеет.

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

- совпадение имен параметров с именами переменных (как здесь: "Номер := Номер). И в справочнике Накладные, и в справочнике Счета-фактуры есть поля, наименования (и типы) которых совпадают, поэтому в такой конструкции нет ничего странного - это допустимо. В синтаксисе параметра первым именем всегда идет имя поля из структуры справочника, который указан в параметре "Документ", а наименование за оператором "присвоения" (:=) - это всегда значение (в данном случае берется значение номера из накладной уже введенном пользователем).

- "_СтавкаНДС". Глобальная переменная, объявленная в проекте, которая содержит числовое значение ставки НДС в процентах.

- Рядом с параметром Привязка может существовать параметр Зависимость (так же как и Привязка - предопределенный параметр).
Этот параметр отвечает за следующее:
- если его значение Да (по
умолчанию), то новые записи в других справочниках или модификация существующих  записей будут делаться в рамках транзакции формы ввода откуда делается запись. Это означает, что если запись добавлена (или модифицирована), но пользователь отказался от записи самой формы ввода, в которой эти изменения происходили программно, то произойдет "откат" сделанных изменений и в другом справочнике.
- если значение Нет, то новые записи или модификации будут происходить в независимой от формы ввода транзакции и, поэтому, даже если пользователь отказался от сохранения изменений в форме ввода, где он находился, то все изменения в другом справочнике сохранятся.
Поэтому можно делать программное изменение в записях других справочниках и из справочника-отчета (такие справочники не имеют собственных записей, а предназначены только для сбора, показа и печати информации).
 

  К содержанию