Как изменить счет списания материалов из эксплуатации (МЦ.04 на МЦ.06) для определенного вида номенклатуры в 1С:Бухгалтерии?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

При работе с типовой конфигурацией 1С:Бухгалтерия 3.0 часто возникает необходимость адаптировать стандартные механизмы под специфические требования учета. В данной статье мы рассмотрим распространенную задачу: изменение логики списания материалов из эксплуатации, когда для определенного вида номенклатуры требуется использовать не стандартный забалансовый счет (например, МЦ.04), а собственный, дополнительно введенный счет (например, МЦ.06).

Предположим, мы ведем учет номенклатуры с видом "Учебная литература" на специально добавленном забалансовом счете МЦ.06. Стандартный документ "Списание материалов из эксплуатации" по умолчанию пытается списать все материалы, относящиеся к инвентарю, со счета МЦ.04. Наша задача — модифицировать этот процесс таким образом, чтобы "Учебная литература" списывалась именно с МЦ.06.

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

Поиск места изменения в типовой конфигурации

Для того чтобы изменить логику определения счета, нам необходимо найти, где формируется список списываемых материалов и какой счет им присваивается. В документе "Списание материалов из эксплуатации" обработка проведения начинается с вызова общего модуля УчетМатериаловВЭксплуатации и его функции СформироватьДвиженияСписаниеИнвентаряИзЭксплуатации(..). Эта функция, в свою очередь, обращается к функции ПодготовитьТаблицуСписанныйИзЭксплуатацииИнвентарь(..), которая выполняет запрос к регистру бухгалтерии для проверки остатков.

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

Посмотрим на исходный фрагмент кода этой функции:


Функция ТекстЗапросаСписаниеИнвентаря(НомераТаблиц)
     НомераТаблиц.Вставить("СписаниеИнвентаряРеквизиты", НомераТаблиц.Количество());
    НомераТаблиц.Вставить("СписаниеИнвентаряТаблица", НомераТаблиц.Количество());
     ТекстЗапроса =
    "ВЫБРАТЬ
    |    Реквизиты.Ссылка КАК Регистратор,
    |    Реквизиты.Дата КАК Период,
    |    Реквизиты.Организация,
    |    Реквизиты.ПодразделениеОрганизации КАК Подразделение
    |ИЗ
    |    Документ.СписаниеМатериаловИзЭксплуатации КАК Реквизиты
    |ГДЕ
    |    Реквизиты.Ссылка = &Ссылка
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ""ИнвентарьИХозяйственныеПринадлежности"" КАК ИмяСписка,
    |    &СинонимИнвентарь КАК СинонимСписка,
    |    МИНИМУМ(ТаблицаИнвентарь.НомерСтроки) КАК НомерСтроки,
    |    ТаблицаИнвентарь.Номенклатура,
    |    ТаблицаИнвентарь.ПартияМатериаловВЭксплуатации,
    |    ТаблицаИнвентарь.ФизЛицо,
    |    ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ИнвентарьИХозяйственныеПринадлежностиВЭксплуатации) КАК СчетМЦ,
    |    СУММА(ТаблицаИнвентарь.Количество) КАК КоличествоМЦ
    |ИЗ
    |    Документ.СписаниеМатериаловИзЭксплуатации.ИнвентарьИХозяйственныеПринадлежности КАК ТаблицаИнвентарь
    |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СписаниеМатериаловИзЭксплуатации КАК Реквизиты
    |        ПО ТаблицаИнвентарь.Ссылка = Реквизиты.Ссылка
    |ГДЕ
    |    Реквизиты.Ссылка = &Ссылка
    |
    |СГРУППИРОВАТЬ ПО
    |    ТаблицаИнвентарь.Номенклатура,
    |    ТаблицаИнвентарь.ПартияМатериаловВЭксплуатации,
    |    ТаблицаИнвентарь.ФизЛицо
    |
    |УПОРЯДОЧИТЬ ПО
    |    ИмяСписка,
    |    НомерСтроки";
     Возврат ТекстЗапроса + ОбщегоНазначенияБПВызовСервера.ТекстРазделителяЗапросовПакета();
КонецФункции

Как мы видим, в этом запросе, в секции ВЫБРАТЬ, для поля СчетМЦ жестко указано значение ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ИнвентарьИХозяйственныеПринадлежностиВЭксплуатации). Это и есть причина того, что система всегда подставляет МЦ.04. Нам необходимо изменить это место, чтобы счет определялся в зависимости от вида номенклатуры.

Решение через изменение запроса в конфигурации

Если мы решаем задачу напрямую в конфигурации (что не рекомендуется для обновляемых систем), то изменение будет заключаться в добавлении конструкции ВЫБОР КОГДА ТОГДА ИНАЧЕ КОНЕЦ. Для этого нам понадобится доступ к справочнику "Виды номенклатуры", чтобы определить, относится ли текущая номенклатура к "Учебной литературе".

  1. В запросе, в секции ВЫБРАТЬ, вместо прямого указания счета ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ИнвентарьИХозяйственныеПринадлежностиВЭксплуатации), мы добавим условие:
  2. 
    |    ВЫБОР
    |        КОГДА ТаблицаИнвентарь.Номенклатура.ВидНоменклатуры = &ВидНоменклатуры
    |            ТОГДА &СчетМЦ06
    |        ИНАЧЕ ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ИнвентарьИХозяйственныеПринадлежностиВЭксплуатации)
    |    КОНЕЦ КАК СчетМЦ,
    
  3. Параметры &ВидНоменклатуры и &СчетМЦ06 необходимо будет установить перед выполнением запроса. Обычно это делается в функции, которая вызывает ТекстЗапросаСписаниеИнвентаря, например, в ПодготовитьПараметрыПроведения документа или напрямую перед вызовом метода Запрос.ВыполнитьПакет().

Решение с помощью расширения (рекомендуемый способ)

Для сохранения возможности обновления типовой конфигурации мы будем использовать расширение. Нам потребуется заместить две функции: ПодготовитьПараметрыПроведения и ТекстЗапросаСписаниеИнвентаря.

1. Замещение функции ПодготовитьПараметрыПроведения

В этой функции мы будем устанавливать параметры запроса, которые понадобятся нам для динамического определения счета: ссылку на вид номенклатуры "Учебная литература" и ссылку на наш новый забалансовый счет МЦ.06.

Создадим новое расширение и добавим в него модуль менеджера документа "Списание материалов из эксплуатации". В этот модуль поместим следующий код, используя директиву &Вместо:


&Вместо("ПодготовитьПараметрыПроведения")
Функция ИНФ_ПодготовитьПараметрыПроведения(ДокументСсылка, Отказ)
    ПараметрыПроведения = Новый Структура;
 
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Реквизиты.Дата КАК Период,
    |    Реквизиты.Организация КАК Организация
    |ИЗ
    |    Документ.СписаниеМатериаловИзЭксплуатации КАК Реквизиты
    |ГДЕ
    |    Реквизиты.Ссылка = &Ссылка";
    Выборка = Запрос.Выполнить().Выбрать();
    Выборка.Следующий();
 
    Если НЕ УчетнаяПолитика.Существует(Выборка.Организация, Выборка.Период, Истина, ДокументСсылка) Тогда
        Отказ = Истина;
        Возврат ПараметрыПроведения;
    КонецЕсли;
 
    Запрос.УстановитьПараметр("СинонимСпецодежда",   НСтр("ru = 'Спецодежда'"));
    Запрос.УстановитьПараметр("СинонимСпецоснастка", НСтр("ru = 'Спецоснастка'"));
    Запрос.УстановитьПараметр("СинонимИнвентарь",    НСтр("ru = 'Инвентарь и хозяйственные принадлежности'"));
    //+++ Добавляем свои параметры
    Запрос.УстановитьПараметр("ВидНоменклатуры" , Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Учебная литература"));
    Запрос.УстановитьПараметр("СчетМЦ06", ПланыСчетов.Хозрасчетный.НайтиПоКоду("МЦ.06")); 
    //---
 
    НомераТаблиц = Новый Структура;
 
    Запрос.Текст = ТекстЗапросаСписаниеСпецодеждыСпецоснастки(НомераТаблиц)
        + ТекстЗапросаСписаниеИнвентаря(НомераТаблиц); // Здесь вызывается замещенная функция!
 
    Результат = Запрос.ВыполнитьПакет();
 
    Для Каждого НомерТаблицы Из НомераТаблиц Цикл
        ПараметрыПроведения.Вставить(НомерТаблицы.Ключ, Результат[НомерТаблицы.Значение].Выгрузить());
    КонецЦикла;
 
    Возврат ПараметрыПроведения;
КонецФункции

Обратите внимание на строки, отмеченные //+++ и //---. Здесь мы получаем ссылки на наш вид номенклатуры и счет МЦ.06 и устанавливаем их в качестве параметров запроса.

2. Замещение функции ТекстЗапросаСписаниеИнвентаря

Далее мы замещаем функцию ТекстЗапросаСписаниеИнвентаря, чтобы включить в нее логику выбора счета. В модуль менеджера документа из расширения добавим:


&Вместо("ТекстЗапросаСписаниеИнвентаря")
Функция ИНФТекстЗапросаСписаниеИнвентаря(НомераТаблиц)
    НомераТаблиц.Вставить("СписаниеИнвентаряРеквизиты", НомераТаблиц.Количество());
    НомераТаблиц.Вставить("СписаниеИнвентаряТаблица", НомераТаблиц.Количество());
 
    ТекстЗапроса =
    "ВЫБРАТЬ
    |    Реквизиты.Ссылка КАК Регистратор,
    |    Реквизиты.Дата КАК Период,
    |    Реквизиты.Организация,
    |    Реквизиты.ПодразделениеОрганизации КАК Подразделение
    |ИЗ
    |    Документ.СписаниеМатериаловИзЭксплуатации КАК Реквизиты
    |ГДЕ
    |    Реквизиты.Ссылка = &Ссылка
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ""ИнвентарьИХозяйственныеПринадлежности"" КАК ИмяСписка,
    |    &СинонимИнвентарь КАК СинонимСписка,
    |    МИНИМУМ(ТаблицаИнвентарь.НомерСтроки) КАК НомерСтроки,
    |    ТаблицаИнвентарь.Номенклатура,
    |    ТаблицаИнвентарь.ПартияМатериаловВЭксплуатации,
    |    ТаблицаИнвентарь.ФизЛицо,
    |    ВЫБОР
    |        КОГДА ТаблицаИнвентарь.Номенклатура.ВидНоменклатуры = &ВидНоменклатуры
    |            ТОГДА &СчетМЦ06
    |        ИНАЧЕ ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ИнвентарьИХозяйственныеПринадлежностиВЭксплуатации)
    |    КОНЕЦ КАК СчетМЦ,
    |    СУММА(ТаблицаИнвентарь.Количество) КАК КоличествоМЦ
    |ИЗ
    |    Документ.СписаниеМатериаловИзЭксплуатации.ИнвентарьИХозяйственныеПринадлежности КАК ТаблицаИнвентарь
    |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СписаниеМатериаловИзЭксплуатации КАК Реквизиты
    |        ПО ТаблицаИнвентарь.Ссылка = Реквизиты.Ссылка
    |ГДЕ
    |    Реквизиты.Ссылка = &Ссылка
    |
    |СГРУППИРОВАТЬ ПО
    |    ТаблицаИнвентарь.Номенклатура,
    |    ТаблицаИнвентарь.ПартияМатериаловВЭксплуатации,
    |    ТаблицаИнвентарь.ФизЛицо
    |
    |УПОРЯДОЧИТЬ ПО
    |    ИмяСписка,
    |    НомерСтроки";
     Возврат ТекстЗапроса + ОбщегоНазначенияБПВызовСервера.ТекстРазделителяЗапросовПакета();
КонецФункции

Здесь мы вставляем нашу логику ВЫБОР КОГДА в поле СчетМЦ, используя параметры &ВидНоменклатуры и &СчетМЦ06, которые мы установили в замещенной функции ИНФ_ПодготовитьПараметрыПроведения.

Причины и отладка ошибки "Указанное количество превышает остаток по счету МЦ.04" в расширении

Если после внедрения расширения вы по-прежнему сталкиваетесь с ошибкой "Указанное количество превышает остаток по счету МЦ.04", это означает, что логика динамического выбора счета в запросе не сработала должным образом, и система по-прежнему пытается найти остатки на МЦ.04 для вашей "Учебной литературы". Фраза "пытается списать 2 раза" является неверной интерпретацией; система просто не находит нужный остаток на неправильном счете.

Давайте разберем по шагам, как локализовать и устранить эту проблему:

  1. Проверка значений параметров в замещенной функции ИНФ_ПодготовитьПараметрыПроведения:
    • Установите точку останова непосредственно перед строками, где вы устанавливаете параметры:
      
      Запрос.УстановитьПараметр("ВидНоменклатуры" , Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Учебная литература"));
      Запрос.УстановитьПараметр("СчетМЦ06", ПланыСчетов.Хозрасчетный.НайтиПоКоду("МЦ.06")); 
      
    • Убедитесь, что Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Учебная литература") возвращает корректную ссылку на ваш предопределенный или добавленный вид номенклатуры. Возможно, вы ошиблись в наименовании или такого вида не существует.
    • Проверьте, что ПланыСчетов.Хозрасчетный.НайтиПоКоду("МЦ.06") возвращает ссылку на ваш созданный счет МЦ.06. Убедитесь, что счет действительно существует в плане счетов и имеет код "МЦ.06".
    • Если какая-либо из этих ссылок не найдена (возвращает неопределенное значение или пустую ссылку), то запрос не сможет корректно использовать эти параметры.
  2. Отладка запроса в расширении с помощью Консоли запросов:
    • Скопируйте полный текст запроса из функции ИНФТекстЗапросаСписаниеИнвентаря.
    • В Консоли запросов 1С вставьте этот текст.
    • Вручную установите параметры &Ссылка (ссылка на ваш тестовый документ списания), &ВидНоменклатуры (та же ссылка, что и в отладчике), &СчетМЦ06 (та же ссылка, что и в отладчике) и &СинонимИнвентарь.
    • Выполните запрос и проанализируйте полученную таблицу. В колонке СчетМЦ вы должны увидеть МЦ.06 для номенклатуры "Учебная литература" и МЦ.04 для других видов. Если все еще видите МЦ.04 для "Учебной литературы", значит, условие КОГДА ТаблицаИнвентарь.Номенклатура.ВидНоменклатуры = &ВидНоменклатуры не срабатывает. Это может быть связано с тем, что свойство ВидНоменклатуры у вашей конкретной номенклатуры не соответствует значению, переданному в параметр.
  3. Проверка фактического счета в функции ПодготовитьТаблицуСписанныйИзЭксплуатацииИнвентарь:
    • Эта функция (в общем модуле УчетМатериаловВЭксплуатации) является типовой и, скорее всего, не замещена вашим расширением. Именно в ней происходит проверка остатков и формируется сообщение об ошибке.
    • Установите точку останова внутри этой функции, непосредственно перед строкой: Если СтрокаТаблицы.КоличествоМЦ > СтрокаТаблицы.КоличествоМЦОстаток Тогда
    • В отладчике внимательно изучите содержимое переменной ТаблицаСписанныеМатериалы (или непосредственно СтрокаТаблицы для проблемной строки).
    • Критически важно проверить значение СтрокаТаблицы.СчетМЦ для той строки, которая вызывает ошибку. Если там по-прежнему стоит МЦ.04, а не МЦ.06, то это окончательно подтверждает, что ваш модифицированный запрос не сработал так, как ожидалось, и не подставил правильный счет.
  4. Проверка метаданных и актуальности расширения:
    • Убедитесь, что расширение активно в режиме предприятия.
    • После любых изменений в расширении, особенно в коде запросов или замещаемых функциях, обязательно обновите конфигурацию базы данных (через F7 в конфигураторе или соответствующей командой в режиме предприятия) и перезапустите клиент 1С.
    • Откройте карточку проблемной номенклатуры "Учебная литература" в режиме предприятия и убедитесь, что в поле "Вид номенклатуры" действительно установлена ссылка на тот вид, который вы ищете в запросе (тот, что находится через Справочники.ВидыНоменклатуры.НайтиПоНаименованию("Учебная литература")). Возможно, номенклатура была создана без указания этого вида или с другим.

Важный момент: убедитесь, что ваш забалансовый счет МЦ.06 имеет нужные субконто. В типовом запросе используются субконто Номенклатура, ПартииМатериаловВЭксплуатации и РаботникиОрганизаций. Если на вашем счете МЦ.06 отсутствуют эти субконто, или они настроены иначе, запрос к регистру бухгалтерии может не дать корректных остатков, даже если счет будет правильным.

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

← На главную