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