При работе в 1С:Бухгалтерии 3.0 пользователи часто сталкиваются с ситуацией, когда при создании нового элемента номенклатуры путем копирования существующего, связанные с ним спецификации не копируются автоматически. Это может вызывать неудобства, требуя ручного создания или копирования спецификаций для каждого нового элемента. Давайте разберем, почему так происходит и как мы можем автоматизировать этот процесс, используя расширения конфигурации.
Причина такого поведения заключается в том, что спецификации номенклатуры в 1С:Бухгалтерии 3.0 хранятся не в табличной части самого элемента номенклатуры, а в отдельном справочнике – СпецификацииНоменклатуры. Эти спецификации связаны с элементом номенклатуры через реквизит «Владелец». Стандартный механизм копирования элементов справочников не предусматривает автоматическое копирование связанных объектов из других справочников, если это явно не запрограммировано.
Для решения этой задачи мы воспользуемся механизмом расширений, который позволяет добавлять или изменять функциональность типовой конфигурации без снятия ее с поддержки. Мы добавим необходимые обработчики событий в форму элемента номенклатуры и в модуль объекта номенклатуры, чтобы перехватывать процесс создания нового элемента и программно копировать все его спецификации.
Мы предлагаем комплексное программное решение, которое позволит вам автоматизировать процесс копирования спецификаций. Для этого нам потребуется создать расширение, добавить реквизит на форму элемента номенклатуры и написать код в обработчиках событий.
Если у вас еще нет расширения, создайте его. Откройте конфигуратор, перейдите в меню "Конфигурация" -> "Расширения конфигурации" -> "Добавить расширение". Присвойте ему осмысленное имя и включите его использование.
Первым шагом нам необходимо добавить временный реквизит на форму элемента номенклатуры, который будет хранить ссылку на исходный элемент номенклатуры, с которого производится копирование. Этот реквизит будет использоваться для передачи информации между различными обработчиками событий.
Для этого в расширении откроем форму элемента справочника Номенклатура. В дереве реквизитов формы нажмем "Добавить реквизит". Зададим следующие параметры:
ЗначениеКопированияСправочникСсылка.НоменклатураПосле создания реквизита, мы обязательно должны перетащить этот реквизит на форму (например, в любую невидимую группу или в конец формы), чтобы он стал доступен на клиенте и его значение могло быть заполнено из параметров формы. Если реквизит не добавлен на форму, он не будет проинициализирован и вы получите ошибку "переменная не определена", как было в исходной теме форума.
Далее мы добавим обработчики событий на форму элемента номенклатуры. Эти обработчики будут выполняться на сервере.
Этот обработчик срабатывает при создании формы на сервере после выполнения стандартной процедуры. Здесь мы проверяем, передан ли параметр ЗначениеКопирования (который содержит ссылку на исходный объект при копировании), и если да, присваиваем его нашему реквизиту формы.
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
ЭтотОбъект.ЗначениеКопирования = Параметры.ЗначениеКопирования;
КонецПроцедуры
Этот обработчик выполняется перед записью объекта на сервере после стандартной процедуры. Мы используем его, чтобы сохранить информацию об исходной номенклатуре и ее основной спецификации в ДополнительныеСвойства нового объекта. Это важно, потому что на момент записи нового элемента номенклатуры мы хотим, чтобы он еще не имел ссылки, а значит, мы сможем передать эту информацию в модуль объекта, где будет выполняться основная логика копирования.
Мы проверяем, что объект новый (Объект.Ссылка.Пустая) и что мы копируем из другого элемента (Не ЭтотОбъект.ЗначениеКопирования.Пустая). Если эти условия выполняются, мы добавляем в ДополнительныеСвойства текущего объекта ссылку на исходную номенклатуру и, если у нее была основная спецификация, ссылку на нее и новую уникальную ссылку, которую получит скопированная основная спецификация.
&НаСервере
Процедура Расш1_ПередЗаписьюНаСервереПосле(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если Объект.Ссылка.Пустая И Не ЭтотОбъект.ЗначениеКопирования.Пустая Тогда
ТекущийОбъект.ДополнительныеСвойства.Вставить("ЗначениеКопирования", ЗначениеКопирования);
ЗначениеКопированияОсновнаяСпецификация = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЗначениеКопирования, "ОсновнаяСпецификацияНоменклатуры");
Если Не ЗначениеКопированияОсновнаяСпецификация.Пустая Тогда
СпецификацииНоменклатурыНоваяСсылка = Справочники.СпецификацииНоменклатуры.ПолучитьСсылку(Новый УникальныйИдентификатор);
ТекущийОбъект.ДополнительныеСвойства.Вставить("СпецификацииНоменклатурыНоваяСсылка", СпецификацииНоменклатурыНоваяСсылка);
ТекущийОбъект.ОсновнаяСпецификацияНоменклатуры = СпецификацииНоменклатурыНоваяСсылка;
ТекущийОбъект.ДополнительныеСвойства.Вставить("ЗначениеКопированияОсновнаяСпецификация", ЗначениеКопированияОсновнаяСпецификация);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Теперь перейдем к модулю объекта справочника Номенклатура. Здесь мы будем выполнять основную логику копирования спецификаций (подобным образом настраивается и автоматическое создание штрихкодов к номенклатуре).
Мы используем обработчик ПриЗаписи, но модифицируем его с помощью директивы &После("ПриЗаписи"). Это гарантирует, что наш код выполнится после стандартной процедуры записи, когда новый объект номенклатуры уже получит свою уникальную ссылку в базе данных. Это критически важно, так как скопированные спецификации должны быть привязаны к этой новой ссылке.
В этом обработчике мы проверяем, было ли выполнено копирование (наличие ЗначениеКопирования в ДополнительныеСвойства) и, если да, вызываем нашу процедуру Расш1_СкопироватьСпецификации.
&После("ПриЗаписи")
Процедура Расш1_ПриЗаписи(Отказ)
Если ЭтотОбъект.ДополнительныеСвойства.Свойство("ЗначениеКопирования") Тогда
Расш1_СкопироватьСпецификации;
КонецЕсли;
КонецПроцедуры
Это основная процедура, которая выполняет копирование всех спецификаций. Мы действуем по следующему алгоритму:
ДополнительныеСвойства.СпецификацииНоменклатуры, чтобы найти все спецификации, связанные с исходной номенклатурой (по полю Владелец).Скопировать(). Этот метод создает новый, еще не записанный в базу данных объект спецификации, который является точной копией исходного по всем реквизитам.Владелец новой спецификации ссылку на новую номенклатуру (ЭтотОбъект.Ссылка), которую мы только что записали. Без этого шага спецификация останется без владельца или будет указывать на старую номенклатуру.ДополнительныеСвойства было указано, что копируемая спецификация является основной, и мы заранее подготовили для нее новую уникальную ссылку, то мы используем метод УстановитьСсылкуНового(). Это гарантирует, что поле ОсновнаяСпецификацияНоменклатуры в только что созданной номенклатуре будет корректно указывать на именно эту скопированную спецификацию.Записать() для новой спецификации, чтобы сохранить ее в базе данных.
&НаСервере
Процедура Расш1_СкопироватьСпецификации
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Владелец", ЭтотОбъект.ДополнительныеСвойства.ЗначениеКопирования);
Запрос.Текст =
"ВЫБРАТЬ
| Таблица.Ссылка КАК Ссылка
|ИЗ
| Справочник.СпецификацииНоменклатуры КАК Таблица
|ГДЕ
| Таблица.Владелец = &Владелец";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий Цикл
НовОбт = Выборка.Ссылка.Скопировать();
НовОбт.Владелец = ЭтотОбъект.Ссылка;
Если ЭтотОбъект.ДополнительныеСвойства.Свойство("ЗначениеКопированияОсновнаяСпецификация") Тогда
Если Выборка.Ссылка = ЭтотОбъект.ДополнительныеСвойства.ЗначениеКопированияОсновнаяСпецификация Тогда
НовОбт.УстановитьСсылкуНового(ЭтотОбъект.ДополнительныеСвойства.СпецификацииНоменклатурыНоваяСсылка);
КонецЕсли;
КонецЕсли;
НовОбт.Записать();
КонецЦикла;
КонецПроцедуры
После добавления кода, убедитесь, что все обработчики событий привязаны к соответствующим событиям в расширении. Это можно проверить в палитре свойств формы и модуля объекта.
Для лучшего понимания представленного решения, используя справочник методов Бухгалтерии предприятия 3.0, давайте подробнее рассмотрим некоторые ключевые механизмы платформы 1С:Предприятие 8:
СпецификацииНоменклатуры: В 1С:Бухгалтерии 3.0, как и во многих других конфигурациях, спецификации для номенклатуры хранятся не в табличной части, а в отдельном справочнике. Связь между элементом номенклатуры и его спецификациями устанавливается через реквизит "Владелец" в справочнике спецификаций. Этот реквизит ссылается на соответствующий элемент номенклатуры.
Скопировать(): Этот метод доступен для объектов большинства справочников и документов. Он создает новый объект в памяти, который является точной копией исходного объекта по всем его реквизитам. Важно: скопированный объект еще не записан в базу данных и не имеет собственной ссылки. Его нужно явно записать методом Записать().
УстановитьСсылкуНового(): Этот метод объекта позволяет задать уникальный идентификатор для нового объекта перед его записью. Это особенно полезно, когда мы хотим, чтобы на новый объект ссылалось какое-либо поле в другом объекте (например, ОсновнаяСпецификацияНоменклатуры). Мы заранее генерируем уникальный идентификатор, присваиваем его полю, а затем, при создании самого объекта, используем УстановитьСсылкуНового(), чтобы этот объект получил именно этот идентификатор.
ДополнительныеСвойства объекта: Это коллекция ключ-значение, доступная у большинства объектов в 1С. Она позволяет временно хранить произвольные данные, которые не являются частью структуры объекта в метаданных. Мы используем ее для передачи контекста (ссылки на исходную номенклатуру и ее основную спецификацию) из формы в модуль объекта при создании нового элемента. Эти свойства не сохраняются в базе данных.
ПриСозданииНаСервереПосле (Форма): Позволяет дополнить стандартную логику создания формы. Используется для получения параметров, переданных форме, например, при копировании.ПередЗаписьюНаСервереПосле (Форма): Срабатывает на сервере непосредственно перед записью данных формы в объект. Здесь мы можем модифицировать объект или добавить в него временные данные (через ДополнительныеСвойства) перед сохранением.&После("ПриЗаписи") (Модуль объекта): Этот модификатор позволяет выполнить нашу процедуру после стандартной процедуры ПриЗаписи объекта. Это критично, поскольку именно в этот момент новый объект уже получает свою постоянную ссылку в базе данных, что позволяет нам корректно связать с ним копируемые спецификации.Хотя программное решение через расширение является наиболее гибким и автоматизированным, существуют и другие способы работы с копированием спецификаций, которые могут быть полезны в различных ситуациях:
Вы можете скопировать спецификацию вручную. Для этого перейдите в раздел "Справочники" -> "Номенклатура", откройте нужный элемент номенклатуры, а затем перейдите по ссылке "Спецификации" или "Материалы" (в зависимости от настроек). В открывшемся списке спецификаций выберите нужную, откройте ее и нажмите кнопку "Скопировать". После этого обязательно измените поле "Владелец" новой спецификации на новую номенклатуру и сохраните ее.
Этот метод подходит для разовых операций или когда требуется внести существенные изменения в спецификацию при копировании.
На рынке существуют готовые внешние обработки для 1С, предназначенные для массового копирования спецификаций. Такие обработки обычно предоставляют удобный интерфейс для выбора исходной и целевой номенклатуры, а также предлагают дополнительные опции, например, замену определенных материалов или пересчет количеств при копировании.
Этот подход полезен, если вам требуется регулярно копировать большое количество спецификаций между разными элементами номенклатуры, или если стандартное копирование не полностью удовлетворяет вашим требованиям по изменению данных.
В некоторых случаях, если вы создаете новую спецификацию программно и хотите, чтобы пользователь мог ее отредактировать перед записью, можно открыть форму новой спецификации, передав ей параметр ЗначениеКопирования. Это позволит форме знать, откуда были взяты данные, и выполнить предзаполнение.
При реализации и использовании данного решения, пожалуйста, обратите внимание на следующие рекомендации:
Скопировать() корректно их обрабатывает, или при необходимости дополните код для их явного копирования.Представленное решение позволяет автоматизировать процесс копирования спецификаций номенклатуры в 1С:Бухгалтерии 3.0, значительно упрощая работу пользователей и повышая эффективность управления данными. Следуя этим инструкциям, вы сможете успешно внедрить данную функциональность в вашу информационную систему.