1с изменить запись в регистре бухгалтерии программно
В некоторых типовых конфигурациях фирмы 1С существует возможность ручной корректировки движений документа по регистрам. В конфигурации 1С: Бухгалтерия 8 для этого, при наличии соответствующих прав, нужно открыть движения документа и установить флаг “Ручная корректировка”. Однако, иногда возникает необходимость выполнить корректировку движений большого количества документов. В этом случае нам понадобится обработка, которая изменит движения документов без перепроведения.
Рассмотрим как изменить движения документа на примере конфигурации 1С: Бухгалтерия 8. Менять будем движения по регистру бухгалтерии “Хозрасчетный”. Пусть перед нами стоит задача заполнить суммы налогового учета по данным бухгалтерского. Предположим, что у нас уже есть обработка, которая выбирает необходимые нам документы и последовательно обрабатывает их с помощью описанной нами процедуры “ИзменитьДвиженияДокумента”. Посмотрим как должна выглядеть эта процедура.
Процедура ИзменитьДвиженияДокумента ( ДокументСсылка )// прочитаем набор записей регистра по документу
НаборЗаписей = РегистрыБухгалтерии . Хозрасчетный . СоздатьНаборЗаписей ( ) ;
НаборЗаписей . Отбор . Регистратор . Установить ( ДокументСсылка ) ;
НаборЗаписей . Прочитать ( ) ;
Если НаборЗаписей . Количество ( ) = 0 Тогда
Возврат ;
КонецЕсли ;
// переберем все записи набора и заполним суммы по налоговому учету
Для каждого Запись из НаборЗаписей Цикл
// перед изменением сумм проверяем ведется ли налоговый учет на выбранном счёте
Если Запись . СчетДт . НалоговыйУчет Тогда
Запись . СуммаНУДт = Запись . Сумма ;
КонецЕсли ;
Если Запись . СчетКт . НалоговыйУчет Тогда
Запись . СуммаНУКт = Запись . Сумма ;
КонецЕсли ;
КонецЦикла ;
// установим признак обмена данными
НаборЗаписей . ОбменДанными . Загрузка = Истина ;
НаборЗаписей . Записать ( ) ;
// установим признак ручной корректировки документа,
// предварительно установив признак обмена данными
ДокументОбъект = ДокументСсылка . ПолучитьОбъект ( ) ;
ДокументОбъект . ОбменДанными . Загрузка = Истина ;
ДокументОбъект . РучнаяКорректировка = Истина ;
ДокументОбъект . Записать ( ) ;
КонецПроцедуры
Хотелось бы отметить, что без проверки ведения налогового учета на счёте, при попытке записать набор, содержащий проводку с ненулевой суммой по счёту на котором не ведется налоговый учет, возникнет ошибка следующего содержания:
Запись не верна! Поле “Сумма (налоговый учет)” должно быть пустым! (Регистр бухгалтерии: Журнал проводок (бухгалтерский и налоговый учет); Номер строки: 1)
Режим обмена данными устанавливается следующими строками:
. . .НаборЗаписей . ОбменДанными . Загрузка = Истина ;
. . .
ДокументОбъект . ОбменДанными . Загрузка = Истина ;
. . .
Это необходимо для того, чтобы не выполнялся программный код, находящийся в обработчиках событий “ПередЗаписью” модуля набора записей регистра бухгалтерии “Хозрасчетный” и модуля корректируемого документа. В каждом из них (для типовых конфигураций) есть проверка следующего вида:
Если ОбменДанными . Загрузка ТогдаВозврат ;
КонецЕсли ;
Движения документа отредактированы вручную и не могут быть автоматически актуализированы
Статья найдена на просторах интернета
Люди кончают самоубийством оттого, что получают по почте одну рекламу.
— Фредерик Бегбедер
Добрый день.
В проводках ряда документов, почему-то слитело значение субконто1Дт.
Перепроводить документы нельзя, поскольку большинство из них Требования-накладные и при перепроведении обороты будут пересчитаны "по среднему" с учётом уже проводок других документов.
Пытаюсь выбрать необходимые проводки, но не получается записать замену. Пожалуйста, подскажите как будет корректно это сделать.
Ниже мой сырой код:
Процедура ВыбратьПроводкиСПустымиСубконто1Дт()
Запрос = Новый Запрос;
Запрос.Текст ;
Запрос.УстановитьПараметр("Счет0830", ПланыСчетов.Хозрасчетный.НайтиПоКоду("08.30"));
Запрос.УстановитьПараметр("Объекты", ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОбъектыСтроительства);
Запрос.УстановитьПараметр("ПустойОбъект", Справочники.ОбъектыСтроительства.ПустаяСсылка());
Результат = Запрос.Выполнить();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Объект = ВыборкаДетальныеЗаписи.Документ.Получитьобъект();
ИзменитьДвиженияДокумента(Объект);
Процедура ИзменитьДвиженияДокумента(Объект)
Набор = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(Объект.Ссылка);
Набор.Прочитать();
Для Каждого Запись из Набор Цикл
Если Запись.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("08.30") И Запись.СубконтоДт = Справочники.ОбъектыСтроительства.ПустаяСсылка() Тогда
Запись.СубконтоДт = Справочники.ОбъектыСтроительства.НайтиПоКоду("6.02.00.00.00.00.00");
КонецЕсли;
КонецЦикла;
Набор.Записать();
Конецпроцедуры
вот так все работает нормально.
Я бы посмотрел в отладчике все подробности, может условие не так написано или еще что. Там вроде несложно разобраться.
Условие неверное. Плюс значение субконто может быть равным "Неопределено", а не пустая ссылка
Для записи значения в субконто надо писАть:
с 01.01.2010 00:00:00 по 31.12.2012 23:59:59 ? Если уже есть отбор по регистратору, то период устанавливать необязательно.
Ну а вообще обычно начальная дата - НачалоДня(Дата1), конечная - КонецДня(Дата2)
спасибо. отбор всё же установил , однако, думаю, что обработка крутится по лишнему циклу несколько раз сначала по выборке, а потом по набору записей:
Процедура ПриОткрытии()
НачПериода = НачалоДня(Дата(2010,02,23,00,00,00));
КонПериода = КонецДня(Дата(2012,12,27,23,59,59));
КонецПроцедуры
Процедура ВыбратьПроводкиСПустымиСубконто1Дт()
Запрос = Новый Запрос;
Запрос.Текст ;
Запрос.УстановитьПараметр("НачПериода", НачПериода);
Запрос.УстановитьПараметр("КонПериода", КонПериода);
Запрос.УстановитьПараметр("Счет0830", ПланыСчетов.Хозрасчетный.НайтиПоКоду("08.30"));
Запрос.УстановитьПараметр("Объекты", ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОбъектыСтроительства);
Запрос.УстановитьПараметр("ПустойОбъект", Справочники.ОбъектыСтроительства.ПустаяСсылка());
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Объект = ВыборкаДетальныеЗаписи.Регистратор.ПолучитьОбъект();
Сообщить("Выборка " + Объект);
ИзменитьДвиженияДокумента(Объект, ВыборкаДетальныеЗаписи);
КонецЦикла;
Конецпроцедуры
Процедура ИзменитьДвиженияДокумента(Объект,ВыборкаДетальныеЗаписи)
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Значение = ВыборкаДетальныеЗаписи.Регистратор;
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
Сообщить("Документ " + Запись.Регистратор);
Если Запись.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("08.30") И Запись.СубконтоДт = Справочники.ОбъектыСтроительства.ПустаяСсылка() Тогда Сообщить("Документ " + ВыборкаДетальныеЗаписи.Регистратор +" Было субконто " + Запись.СубконтоДт + " Сумма " + Запись.Сумма + " Счет " + Запись.СчетДт); Запись.СубконтоДт = Справочники.ОбъектыСтроительства.НайтиПоКоду("6.02.00.00.00.00.00");
Сообщить("Документ " + ВыборкаДетальныеЗаписи.Регистратор +" Стало субконто " + Запись.СубконтоДт + " Сумма " + Запись.Сумма + " Счет " + Запись.СчетДт); КонецЕсли;
КонецЦикла;
НаборЗаписей.Записать();
Сообщить("Записано " + ВыборкаДетальныеЗаписи.Регистратор + " Субконто " + Запись.СубконтоДт);
КонецПроцедуры
Всем огромное спасибо. В итоге получилось так (вроде бы работает):
Процедура КнопкаВыполнитьНажатие(Кнопка)
Сообщить("Время начала " + ТекущаяДата());
ВыбратьПроводкиСПустымиСубконто1Дт();
Сообщить("Время окончания " + ТекущаяДата());
Процедура ВыбратьПроводкиСПустымиСубконто1Дт()
Запрос = Новый Запрос;
Запрос.Текст ;
Запрос.УстановитьПараметр("НачПериода", НачПериода);
Запрос.УстановитьПараметр("КонПериода", КонПериода);
Запрос.УстановитьПараметр("Счет0830", ПланыСчетов.Хозрасчетный.НайтиПоКоду("08.30"));
Запрос.УстановитьПараметр("Объекты", ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОбъектыСтроительства);
Запрос.УстановитьПараметр("ПустойОбъект", Справочники.ОбъектыСтроительства.ПустаяСсылка());
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Объект = ВыборкаДетальныеЗаписи.Регистратор;
Сообщить("Выборка " + Объект);
ИзменитьДвиженияДокумента(ВыборкаДетальныеЗаписи);
КонецЦикла;
Процедура ИзменитьДвиженияДокумента(ВыборкаДетальныеЗаписи)
НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Значение = ВыборкаДетальныеЗаписи.Регистратор;
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
Сообщить("Документ " + Запись.Регистратор);
Если Запись.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("08.30") И Запись.СубконтоДт.ОбъектыСтроительства = Справочники.ОбъектыСтроительства.ПустаяСсылка() Тогда
Сообщить("Было субконто " + Запись.СубконтоДт.ОбъектыСтроительства + " Сумма " + Запись.Сумма + " Счет " + Запись.СчетДт);
Запись.СубконтоДт.ОбъектыСтроительства = Справочники.ОбъектыСтроительства.НайтиПоКоду("6.02.00.00.00.00.00");
Сообщить("Стало субконто " + Запись.СубконтоДт.ОбъектыСтроительства + " Сумма " + Запись.Сумма + " Счет " + Запись.СчетДт);
КонецЕсли;
КонецЦикла;
НаборЗаписей.Записать();
Сообщить("Записано " + ВыборкаДетальныеЗаписи.Регистратор + " Субконто " + Запись.СубконтоДт.ОбъектыСтроительства);
КонецПроцедуры
Процедура ВыбПериодНажатие(Элемент)
НастройкаПериода = Новый НастройкаПериода;
НастройкаПериода.РедактироватьКакИнтервал = Истина;
НастройкаПериода.РедактироватьКакПериод = Истина;
НастройкаПериода.ВариантНастройки = ВариантНастройкиПериода.Период;
НастройкаПериода.УстановитьПериод(НачПериода, ?(КонПериода='0001-01-01', КонПериода, КонецДня(КонПериода)));
Если НастройкаПериода.Редактировать() Тогда
НачПериода = НастройкаПериода.ПолучитьДатуНачала();
КонПериода = НастройкаПериода.ПолучитьДатуОкончания();
КонецЕсли;
КонецПроцедуры
Процедура ПриОткрытии()
НачПериода = НачалоДня(Дата(2010,02,23,00,00,00));
КонПериода = КонецДня(Дата(2012,12,27,23,59,59));
КонецПроцедуры
Манипулирование записями регистров без использования регистратора
В 1С:Предприятии 8 все регистры, кроме регистров сведений, всегда связаны с регистраторами. Регистры сведений могут быть независимыми или также подчиненными регистратору. В этом разделе мы опишем работу с регистрами, подчиненными регистраторам.
В большинстве случаев записи регистров, подчиненных регистраторам, создаются при проведении документов. Это наиболее "естественный" способ создания записей. В этом случае в процессе проведения документа формируются записи регистра, и, тем самым, происходит отражение в учете события описываемого документом.
Однако в 1С:Предприятии 8 существует возможность изменять записи регистров без участия документа. При этом следует учитывать, что каждая запись регистра всегда подчинена одному и только одному регистратору (документу). Поэтому с точки зрения "времени жизни" записи всегда подчинены конкретным регистраторам. Однако, записи могут изменяться без участия самого документа. Главное, чтобы в них имелась ссылка на документ.
Для изменения записей регистров, подчиненных регистраторам, используются наборы записей. При этом всегда используется отбор по регистратору. То есть совокупность записей, подчиненных одному регистратору, является "гранулой" изменения регистра. Нельзя добавлять или удалять отдельные записи. Можно только считывать и записывать записи по регистратору.
При изменении записей регистра можно использовать набор записей, входящий в коллекцию движений документа (свойство Движения объекта ДокументОбъект). Однако это не обязательно. Для изменения записей регистра можно использовать и набор записей созданный с помощью менеджера регистра.
Таким образом, чтобы изменить записи регистра необходимо:
- создать набор записей;
- установить отбор по определенному регистратору;
- прочитать набор;
- изменить записи набора;
- записать набор.
Например, чтобы установить значение реквизита во всех записях регистра можно использовать следующий алгоритм.
//Выберем всех регистраторов регистра
Запрос = Новый Запрос;
Запрос.Текст ;
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
//Обойдем регистраторов
Пока Выборка.Следующий() Цикл
Сообщить("Изменение записей по регистратору: " + Выборка.Регистратор);
//Для каждого регистратора выполним изменение набора записей
НаборЗаписей = РегистрыНакопления.УчетНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Значение = Выборка.Регистратор;
НаборЗаписей.Прочитать();
Для каждого Запись Из НаборЗаписей Цикл
Запись.Реквизит1 = "Тест";
КонецЦикла;
НаборЗаписей.Записать();
КонецЦикла;
В приведенном примере выполнялось изменение записей. Для добавления записей, если их нет у регистратора, можно выполнять запись без считывания. Для удаления записей можно выполнять запись пустого набора без выполнения считывания.
Заметим, что для добавления большого количества записей по одному регистратору существует возможность записывать записи без замещения. Это регулируется параметром метода Записать(). Такая возможность позволяет добавлять записи, не помещая их всех одновременно в оперативную память.
В регистрах расчетов кроме отбора по регистратору для набора записей можно также установить отбор по другим значениям измерений (только по равенству). Это позволяет выполнить изменение части записей, подчиненных одному регистратору.
Читайте также: