Как получить остатки товаров на момент документа в 1С 7.7 с использованием библиотеки 1С++ для DBF-баз?

Программист 1С v7.7 Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке сложных учетных механизмов в 1С:Предприятии 7.7 стандартных средств системы иногда оказывается недостаточно, особенно когда требуется высокая производительность при проведении документов задним числом. Использование библиотеки 1С++ позволяет обращаться к данным базы напрямую через SQL-запросы. Однако при переходе от SQL-версии к файловой (DBF) возникают существенные различия в реализации. Давайте разберем, как правильно организовать получение остатков в DBF-базах.

Понимание архитектуры работы с остатками

Основное отличие между SQL-версией и файловой версией при работе с 1С++ заключается в способе доступа к данным регистра. В SQL-версии мы можем использовать специализированные конструкции метаданных, такие как $РегистрОстатки. В DBF-версии такие конструкции недоступны, так как парсер библиотеки не может автоматически объединять разрозненные таблицы итогов и движений.

Для DBF-базы нам необходимо самостоятельно построить логику запроса, которая будет:

  1. Обращаться к таблице итогов $РегистрИтоги на начало периода.
  2. Добавлять к ним движения из таблицы $Регистр за период с начала месяца до момента времени нужного документа.
  3. Учитывать специфику хранения движений (приход/расход) с помощью поля debkred.

Пошаговая реализация функции получения остатков

Чтобы получить актуальные остатки товаров на момент проведения документа, мы создадим универсальную функцию. Важно учитывать, что при прямом доступе к DBF-файлам через OLEDB необходимо управлять блокировками и буферизацией данных.

Ниже представлен пример кода, который объединяет накопленные итоги и текущие движения:


Функция ПолучитьОстаткиДокПр(ТекДок) Экспорт
    Если МонопольныйРежим=1 Тогда Возврат 0; КонецЕсли;
    Попытка
        База = СоздатьОбъект("OLEDBData");
        Соединение =" |Provider=VFPOLEDB.1; |Data Source=" + КаталогИБ + "; |Mode=Read; |";
        Рез = База.Соединение(Соединение);
        Запрос = База.СоздатьКоманду;
    Исключение Возврат 0; КонецПопытки;

    // Установка параметров соединения для стабильной работы
    Запрос.Выполнить("EXECSCRIPT('SET ANSI OFF')");
    Запрос.Выполнить("EXECSCRIPT('SET REPROCESS TO 60 SECONDS')");
    Запрос.Выполнить("EXECSCRIPT('SET REFRESH TO 0,-1')");
    Запрос.Выполнить("Exec('SET TABLEVALIDATE TO 0')");

    ТекстЗапроса = "
    |SELECT 
    | Рег.Товар as [Товар $Справочник.Каталог], 
    | SUM(Рег.Количество) as Количество, 
    | SUM(Рег.Сумма) as Сумма, 
    | SUM(Рег.СуммаВалюта) as СуммаВалюта 
    |FROM (
    | SELECT 
    |  $Р.Товар AS Товар, 
    |  $Р.Количество AS Количество, 
    |  $Р.Сумма AS Сумма, 
    |  $Р.СуммаВалюта AS СуммаВалюта 
    | FROM $РегистрИтоги.Товары as Р 
    | WHERE (period = :ПредМесяц~~) AND ($Р.Склад=:Склад)
    | UNION ALL
    | SELECT 
    |  $Р.Товар AS Товар, 
    |  $Р.Количество * (1 - Р.debkred * 2) AS Количество, 
    |  $Р.Сумма * (1 - Р.debkred * 2) AS Сумма, 
    |  $Р.СуммаВалюта * (1 - Р.debkred * 2) AS СуммаВалюта 
    | FROM $Регистр.Товары AS Р 
    | INNER JOIN 1sjourn jr ON Р.iddoc = jr.iddoc 
    | AND (DTOS(jr.date)+jr.time+jr.iddoc BETWEEN :НачалоМесяца AND :ПредДата~) 
    | WHERE ($Р.Склад=:Склад)
    |) AS Рег 
    |GROUP BY Рег.Товар";

    Запрос.УстановитьТекстовыйПараметр("Склад", ТекДок.Склад);
    Запрос.УстановитьТекстовыйПараметр("ПредДата", СформироватьПозициюДокумента(ТекДок, -1));
    Запрос.УстановитьТекстовыйПараметр("НачалоМесяца", начМесяца(ТекДок.ДатаДок));
    Запрос.УстановитьТекстовыйПараметр("ПредМесяц", начМесяца(начМесяца(ТекДок.ДатаДок)-1));

    ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
    Возврат ТЗ;
КонецФункции

Ключевые технические нюансы

При анализе данного кода обратите внимание на следующие важные моменты, которые обеспечивают корректный расчет:

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

← На главную