Программная работа с документами в 1С 8.3

Apr 17, 2022 17:37

ДокументыМенеджер

Объект ДокументыМенеджер позволяет получить доступ ко всем менеджерам документов. Это можно сделать перебрав все менеджеры в цикле или обратившись к конкретному менеджеру по имени. Также данный объект позволяет проверить является ли ссылка ссылкой на какой-нибудь документ:

//получение конкретного менеджера документа по имени
МенеджерДокаПриход = Документы.ПриходТовара;
МенеджерДокаРасход = Документы["РасходТовара"];

//перебор всех менеджеров документа
Для Каждого МенеджерДока Из Документы Цикл
Сообщить(МенеджерДока);
КонецЦикла;

СсылкаНаЧтото = ПолучитьСсылкуНаЧтото();

//проверка является ли ссылка ссылкой на документ
ВсеДоки = Документы.ТипВсеСсылки();
Если ВсеДоки.СодержитТип(ТипЗнч(СсылкаНаЧтото)) Тогда
//это ссылка на документ
Иначе
//что-то другое
КонецЕсли;


Создание документа программно

Чтобы программно создать документ нужно использовать метод менеджера документа СоздатьДокумент:

//создаем новый документ
ПриходныйДок = Документы.ПриходТовара.СоздатьДокумент();
//обязательно заполняем дату
ПриходныйДок.Дата = ТекущаяДатаСеанса();
//... заполняем другие реквизиты
ПриходныйДок.Поставщик = СсылкаНаПоставщика;
//записываем в базу данных
ПриходныйДок.Записать();

Программное заполнение документа

Для программного заполнения документа нужно обращаться к каждому реквизиту объекта по имени, через точку от объекта:

//создаем новый документ
ПриходныйДок = Документы.ПриходТовара.СоздатьДокумент();
//обязательно заполняем дату
ПриходныйДок.Дата = ТекущаяДатаСеанса();
//заполняем реквизиты Поставщик, Склад, Комментарий
ПриходныйДок.Поставщик = СсылкаНаПоставщика;
ПриходныйДок.Склад = СсылкаНаСклад;
ПриходныйДок.Комментарий = "документ создан программно";
//записываем в базу данных
ПриходныйДок.Записать();

Программное заполнение табличной части документа

К табличной части документа можно обратиться по имени, через точку от объекта. Затем через метод Добавить добавить новую строку табличной части. К реквизитам строки можно обращаться по имени, через точку от строки. В целом работа с табличной частью документа похожа на работу с таблицей значений:

//создаем новый документ
ПриходныйДок = Документы.ПриходТовара.СоздатьДокумент();
//добавим несколько строк в табличную часть СписокТоваров
НоваяСтрТЧ = ПриходныйДок.СписокТоваров.Добавить();
НоваяСтрТЧ.Товар = СсылкаНаТоварОдин;
НоваяСтрТЧ.Количество = 18;

НоваяСтрТЧ = ПриходныйДок.СписокТоваров.Добавить();
НоваяСтрТЧ.Товар = СсылкаНаТоварДва;
НоваяСтрТЧ.Количество = 36;

//можно загрузить строки из таблицы значений
//имена колонок должны совпадать с именами реквизитов табличной части
ПриходныйДок.СписокТоваров.Загрузить(НекаяТаблица);

//записываем в базу данных
ПриходныйДок.Записать();

Программное изменение документа

Изменить документ можно только через программный объект. Для этого методом ПолучитьОбъект нужно получить из ссылки объект и потом изменить его реквизиты:

//получаем объект из ссылки
ПриходныйДок = СсылкаНаДок.ПолучитьОбъект();
//меняем поставщика
ПриходныйДок.Поставщик = СсылкаНаПоставщика;
//записываем
ПриходныйДок.Записать();

Программное копирование документа

Для создания копии объекта предназначен метод Скопировать. Данный метод есть как у ссылки на документ, так и у объекта:

//копия документа через ссылку
НоваяКопия = СсылкаНаДок.Скопировать();
НоваяКопия.Дата = ТекущаяДатаСеанса();
НоваяКопия.Записать();

//копия документа через объект
ДокОбъект = СсылкаНаДок.ПолучитьОбъект();
НоваяКопия = ДокОбъект.Скопировать();
НоваяКопия.Дата = ТекущаяДатаСеанса();
НоваяКопия.Записать();

Программное удаление документа

Пометить на удаление документ можно с помощью метода УстановитьПометкуУдаления. Параметром нужно передать значение пометки на удаление. При установке пометки на удаление документ автоматически распроводится, если он был проведен и записывается. Также можно полностью удалить документ из базы методом Удалить:

//устанавливать пометку на удаление можно только через объект
ПриходныйДок = СсылкаНаДок.ПолучитьОбъект();

//пометить на удаление
ПриходныйДок.УстановитьПометкуУдаления(Истина);

//снять пометку на удаление
ПриходныйДок.УстановитьПометкуУдаления(Ложь);

//удаление документа из базы
ПриходныйДок.Удалить();

Программное проведение документа

У документа нет отдельного метода для проведения документа. Проведение - это запись документа с проведением. Для проведения документа используется метод Записать, в который параметром нужно передать режим записи документа. Всего есть три режима записи: запись, проведение, отмена проведения. Если параметр не указан, то используется запись:

ПриходныйДок = Документы.ПриходТовара.СоздатьДокумент();
ПриходныйДок.Дата = ТекущаяДатаСеанса();

//запись документа
ПриходныйДок.Записать(РежимЗаписиДокумента.Запись);
//тоже запись
ПриходныйДок.Записать();

//проведение документа
ПриходныйДок.Записать(РежимЗаписиДокумента.Проведение);

//отмена проведения документа
ПриходныйДок.Записать(РежимЗаписиДокумента.ОтменаПроведения);

Программная работа с движениями документа

Через свойство Движения можно обращаться к движениям проведенного документа и даже редактировать их. Рассмотрим на примере:

ДатаПоиска = ТекущаяДатаСеанса();
ПриходныйДок = Документы.ПриходТовара.НайтиПоНомеру("АА0000003", ДатаПоиска);

ДокПриходОбъект = ПриходныйДок.ПолучитьОбъект();
//получаем все движения документа
ДвиженияДока = ДокПриходОбъект.Движения;

//перебор всех регистров, по которым выполняются движения документом
Для Каждого Рег Из ДвиженияДока Цикл
Сообщить(Рег);
КонецЦикла;

//количество регистров из коллекции движений
КолвоРег = ДвиженияДока.Количество();

//поиск по имени регистра
РегОстатки = ДвиженияДока.Найти("ОстаткиТоваров");
Если Не РегОстатки = Неопределено Тогда
//есть такой регистр
//читаем записи регистра из базы данных
РегОстатки.Прочитать();
//перебирам в цикле и увеличиваем количество вдвое
Для Каждого ЗаписьРег Из РегОстатки Цикл
ЗаписьРег.Количество = ЗаписьРег.Количество * 2;
КонецЦикла;
//записываем
РегОстатки.Записать();
КонецЕсли;

Программный поиск документа

Чтобы программно найти документ можно использовать методы НайтиПоНомеру и НайтиПоРеквизиту менеджера документа.

НайтиПоНомеру

В метод НайтиПоНомеру первым параметром передается номер документа, вторым дата, для определения периода, в котором нужно искать документ. Если для документа указана периодичность = В пределах года, то можно передать любую дату за этот год:

ДатаПоиска = Дата(2021,1,1);
//в настройках нумерации указана Периодичность = В пределах года
ПриходныйДок = Документы.ПриходТовара.НайтиПоНомеру("000000017", ДатаПоиска);
//поиск будет выполняться среди документов за 2021 год с номером 000000017

//в настройках нумерации указана Периодичность = В пределах месяца
ПриходныйДок= Документы.ПриходТовара.НайтиПоНомеру("000000017", ДатаПоиска);
//поиск будет выполняться среди документов за январь 2021 год с номером 000000017

//в настройках нумерации указана Периодичность = Непериодический
//дату можно не указывать
ПриходныйДок = Документы.ПриходТовара.НайтиПоНомеру("000000017");
//поиск будет выполняться среди всех документов

//если документ не найден, то в ПриходныйДок будет пустая ссылка
Если ПриходныйДок = Документы.ПриходТовара.ПустаяСсылка() Тогда
//не нашли
ИначеЕсли ПриходныйДок = Неопределено Тогда
//для документа указана нулевая длина номера
Иначе
//ПриходныйДок - ссылка на документ
КонецЕсли;

НайтиПоРеквизиту

Метод НайтиПоРеквизиту принимает два параметра: имя реквизита и значение реквизита. Если реквизит имеет тип Строка, то поиск выполняется по точному соответствию. Нельзя искать по реквизиту с типом ХранилищеЗначения или неограниченная строка.

//поиск по реквизиту
//первый параметр - имя реквизита
//второй параметр - значение реквизита
ПриходныйДок = Документы.ПриходТовара.НайтиПоРеквизиту("Поставщик", СсылкаНаПоставщика);

//если документ не найден, то в ПриходныйДок будет пустая ссылка
Если ПриходныйДок = Документы.ПриходТовара.ПустаяСсылка() Тогда
//не нашли
Иначе
//ПриходныйДок - ссылка на найденный документ
//если было несколько документов с таким значением реквизита, то
//будет найден первый попавшийся
КонецЕсли;

Выборка документов

Чтобы получить выборку документов можно воспользоваться методом Выбрать менеджера документа. Затем полученную выборку можно перебрать с помощью цикла Пока. На каждом витке цикла будут данные об одном документе. Через параметры метода можно ограничить выборку по периоду или по реквизитам.

//выборка всех документов
ВыборкаПриходов = Документы.ПриходТовара.Выбрать();
Пока ВыборкаПриходов.Следующий() Цикл
//через выборку есть доступ ко всем реквизитам объекта
Сообщить(ВыборкаПриходов.Номер);
Сообщить(ВыборкаПриходов.Поставщик);
//также через выборку можно получить объект
ДокОбъект = ВыборкаПриходов.ПолучитьОбъект();
КонецЦикла;

//выборка документов за 2 месяца
ВыборкаПриходов = Документы.ПриходТовара.Выбрать(Дата(2021,1,1), Дата(2021,2,28));

//выборка всех документов, у которых дата больше 1 марта 2021
ВыборкаПриходов = Документы.ПриходТовара.Выбрать(Дата(2021,3,1));

//выборка всех документов, у которых дата меньше 15 марта 2021
ВыборкаПриходов = Документы.ПриходТовара.Выбрать(, Дата(2021,3,15));

//выборка документов с конкретной датой
ОтборДок = Новый Структура("Дата", Дата(2021,3,22));
ВыборкаПриходов = Документы.ПриходТовара.Выбрать(,, ОтборДок);

//выборка документов с конкретным значением реквизита
ОтборДок = Новый Структура("Поставщик", СсылкаНаПоставщика);
ВыборкаПриходов = Документы.ПриходТовара.Выбрать(,, ОтборДок);

//выборка отсортированная по убыванию даты
ВыборкаПриходов = Документы.ПриходТовара.Выбрать(,,, "Дата Убыв");

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

Программная работа с ссылкой на документ

Через ссылку на документ можно обратиться к реквизитам объекта. При этом будет неявно выполнен запрос к базе данных для получения значения реквизита. Так как работа с базой данных возможна только на сервере, то на клиенте нельзя от ссылки получать значения реквизитов:

Поставщик = СсылкаНаДокПриход.Поставщик;
ДатаДок = СсылкаНаДокПриход.Дата;
//однако на клиенте такой код не сработает с ошибкой:
// поле объекта не обнаружено

Для получения пустой ссылки можно использовать метод ПустаяСсылка. Для проверки на пустую ссылку можно воспользоваться методом Пустая:

//получение пустой ссылки на документ
ПустойДокПриход = Документы.ПриходТовара.ПустаяСсылка();

//проверка на пустую ссылку
Если ПустойДокПриход.Пустая() Тогда
//пустая ссылка
КонецЕсли;
//или так
Если ПустойДокПриход = Документы.ПриходТовара.ПустаяСсылка() Тогда
//тоже пустая ссылка
КонецЕсли;

Сопоставление документов по идентификатору

У каждого документа есть уникальный идентификатор, который присваивается при первой записи документа и не может быть изменен. Часто при обмене между двумя базами данных требуется сопоставлять документы. Для этого можно использовать идентификаторы.

Пример выгрузки идентификатора документа. Уникальный идентификатор получается из ссылки методом УникальныйИдентификатор:

ВыборкаПриходов = Документы.ПриходТовара.Выбрать();
Пока ВыборкаПриходов.Следующий() Цикл
//получаем уникальный идентификатор
УИДПрихода = ВыборкаПриходов.Ссылка.УникальныйИдентификатор();
//преобразуем в строку
УИДПриходаСтрокой = Строка(УИДПрихода);
//дальше записываем строку в файл обмена
КонецЦикла;

Пример сопоставления документов по идентификатору. Здесь используется метод ПолучитьСсылку для получения ссылки на документ по уникальному идентификатору и метод УстановитьСсылкуНового чтобы уникальный идентификатор нового документа был равен уникальному идентификатору, полученному из другой базы.

//ТаблицаЗагрузки - некая таблица с данными из другой базы
Для Каждого Стр ИЗ ТаблицаЗагрузки Цикл
УИДПриходаСтрокой = Стр.УИД;
//создаем уникальный идентификатор
УИДПрихода = Новый УникальныйИдентификатор(УИДПриходаСтрокой);

//получаем ссылку на документ
ПриходныйДок = Документы.ПриходТовара.ПолучитьСсылку(УИДПрихода);
//из ссылки получаем объект
ДокПриходОбъект = ПриходныйДок.ПолучитьОбъект();
Если ДокПриходОбъект = Неопределено Тогда
//если объект = Неопределено значит документа с таким
//идентификатором еще нет, создаем его
ДокПриходОбъект = Документы.ПриходТовара.СоздатьДокумент();
//...заполнение

//до записи обязательно устанавливаем полученную ссылку
//тогда идентификаторы будут совпадать
ДокПриходОбъект.УстановитьСсылкуНового(ПриходныйДок);
ДокПриходОбъект.Записать();
Иначе
//уже есть документ с таким идентификатором,
//перезаписываем его
КонецЕсли;
КонецЦикла;

Смотрите также:
Электронный учебник по программированию в 1С
Рекомендации по изучению программирования 1С с нуля
Игра "Кто хочет стать миллионером?" с вопросами на определенную тематику (язык программирования JavaScript, английские, немецкие, французские, испанские, португальские, ни­дер­ландские, итальянские слова, электробезопасность, промышленная безопасность, бокс и т.п.), написанная на 1С
Программирование в 1С 8.3 с нуля - краткий самоучитель
Комплексная подготовка программистов 1С:Предприятие 8.2
Сайты с уроками программирования и со справочниками
Youtube-каналы с уроками программирования
Сайты для обучения программированию
Лекции и уроки

программирование

Previous post Next post
Up