Типичная ситуация в работе программиста 1С – приходит вдруг с утра к вам в кабинет финансовый директор компании и заявляет. Товарищ программист, что-то какая-то бодяга у нас в управленческом учете. На кой ляд нам такое количество разных видов приходных документов? И на мелочевку, и на бытовую технику, и продукты питания. Наши экономисты уже забодались бегать от одного документа к другому. Хочу чтобы это всё учитывалось одним документом…и уходит…а вы после этого ещё минут пять сидите вот так:
…но это если вы только начинаете программировать на 1С, а вот если есть небольшой опыт, то сразу же поймете, что задача хотя и нетривиальная, но всё же не такая сложная. Давайте убедимся в этом наглядно. Добавить нужные табличные части в документ поступления товаров услуг – это не проблема, и мы это делать уже умеем. А вот что делать с данными? Как их после этого перебросить в этот документ, ну не вводить же их заново!
Для начала всё-таки модернизируем наш документ ПоступлениеТоваровУслуг, создав там табличные части по тому виду, которые они были в этих документах, но их придётся переименовать, т.к. нельзя в одном объекте делать табличные части или реквизиты с одинаковым названием:
На форму тоже добавим все эти табличные части.
Теперь саму форму нужно немного доработать – помните мы считали сумму по строке при помощи процедуры общего модуля? Она ведь сейчас будет считать только для табличной части “Товары”, т.к. мы это в ней явно указали, а для остальных табличных частей будет выдавать ошибку выполнения, т.к. программа будет пытаться обратиться к текущей строке таблицы Товары, в то время как текущая строка будет находится вообще в другой табличной части. Давайте доработаем код процедуры и сделаем его таким:
Видите, я могу обратиться к табличной части не только “через точку”, но и через именованный массив – программа будет брать имя табличной части из переменной ИмяТабличнойЧасти, которое мы будем передавать при вызове этой процедуры:
Кстати, а вы не заметили, что что-то тут лишнее? Две процедуры выполняют одно и то же. Давайте мы оставим только одну процедуру и дадим ей немного общее наименование, а вторая вообще больше не нужна:
Но на эти процедуры ссылались события в двух колонках – “Количество” и “Цена”, по этому там тоже надо теперь указать эту новую процедуру:
Тоже самое сделать и для колонки количества, указав ту же самую процедуру:
Добавим теперь на каждую табличную часть новую вкладку со своей табличной частью, а то сейчас у нас только товары и услуги. Делается это при помощи добавления новой страницы (это сама вкладка):
, указав элемент “Страница”:
, а затем и самой табличной части перетаскиванием справа налево:
Теперь дадим самой вкладке вразумительное имя по аналогии предыдущими:
Теперь добавьте реквизит документа “ИдентификаторСтарогоДокумента”, значение которого станет понятно чуть позже:
Теперь познакомимся с новый объектом метаданных – Обработка, и сразу же добавим новую с именем “ПереносДанных”:
Сделайте ещё одну подсистему и включите туда эту обработку:
Теперь добавим форму:
Теперь на форму нужно добавить единственную кнопку, по нажатию которой будет происходить перенос данных из существующих документов в наш новый переделанный с множеством табличных частей. Добавьте новый элемент “Кнопка” на форму:
К слову говоря, подобным способом добавляются элементы на все формы, в т.ч. справочников и документов, но мы делали это немного другим способом, т.к. у нас был элемент отображения реквизита и мы просто перетягивали его справа налево.
Кнопка появилась, но теперь нужно добавить команду – реакцию по нажатию на кнопку. Для этого нужно открыть вкладку “Команды” и добавить новую:
Теперь в свойствах кликнуть по созданию обработчика:
В этот раз обработчик будет включать в себя две процедуры – на клиенте и на сервере, т.к. нам понадобятся процедуры и функции, которые характерны только для серверного исполнения. В результате платформа автоматически подготовит их для программирования:
Теперь нужно возвратиться обратно в графическое представление формы и привязать кнопку к команде и дать человеческие наименования:
Переходим снова в код. Делаем так:
Давайте разбираться что тут. Сначала я сделал запрос для того чтобы перебрать все уже созданные документы ПоступлениеМелочевки.
Получаю уникальный идентификатор каждого документа. Этот идентификатор – объект платформы, который легко можно преобразовать в строку. Строка получается 36 символов. Каждый объект данных 1С имеет уникальную идентификацию в пределах одной базы. Она нужна мне чтобы привязать создаваемые автоматически документы с исходным “старым” документом. Такая идентификация мне нужна чтобы однозначно определить перегружался ли этот документ уже или нет, на случай, если я захочу запустить обработку повторно. Повторный запуск может потребоваться, если при первом что-то пошло не так или мы уже успели внести ещё данных по мелочевки “старым” способом.
НайтиДокументПоИдентификатору() – это нестандартная функция, как может показаться, которая будет искать документ по признаку идентификатора; я разместил её в этом же модуле:
Эта функция при помощи простого запроса с условием ищет тот документ ПоступленияТоваровУслуг, где реквизит ИдентификаторСтарогоДокумента будет равен идентификатору исходного документа (мелочёвки, продуктов питания и т.п.). Если результат поиска отрицательный, то функция возвратит значение равное “Неопределено”.
После этого я проверяю удалось ли найти документ. Если не удалось, то будет создан новый и сразу же определен реквизит с идентификатором и дата (без указания даты документ не удастся записать).
Следующие действия – это перенести построчно табличную часть с товарами. Тут должно быть понятно – берём строку исходного документа – создаём строку конечного документа.
В результате получаем что-то вроде этого:
Тут хорошо видно, что два первых документа без идентификатора – это те, что создавали интерактивно (вручную), а два с идентификатором – это те, что переносили обработкой (именно тогда мы его устанавливали). Сам документ теперь выглядит так:
Задание по уроку:
1. Добавьте на форму документа ПоступлениеТоваровУслуг страницу с табличной части “ПродуктыПитания”, сделайте необходимый расчет суммы по строке.
2. Добавьте в обработку перенос документа ПродуктыПитания
3. Ранее я говорил, что перед проведением документа всегда автоматически происходит его запись, однако при этом принудительно делаю перед этим запись. Как думаете, почему я так сделал?
Если всё получилось как нужно – молодцы! Если нет, давайте разберёмся что не так.
El Vinto, 2023