Как получить сумму долга по каждой организации без повторных обращений?

База знаний Одина — Одинэсника Форумы ODIN — Форум по 1С Предприятию Как получить сумму долга по каждой организации без повторных обращений?

Просмотр 1 ветки ответов
  • Автор
    Сообщения
    • #35657
      Телеграм группа https://t.me/odineskiOdineski
      Участник

        СКАТ — Профессионал 5.0″ (5.26.01.12)
        Я имею таблицу, в которой есть Столбцы : Организация, Договор, Контрагент. Мне нужно по каждой организации иметь сумму долга. при нажитии на кнопку я создаю программную таблицу значений с этими полями. Не хчу чтобы он для каждой строчки к запросу опять обращался, как ее поместить в запрос. Чтобы в условие попадало организация, конртагент и договор. Сам запрос для одного поиска такой.
        ВЫБРАТЬ
        ВзаиморасчетыСКонтрагентамиОстатки.ДоговорКонтрагента КАК ДоговорКонтрагента,
        ВзаиморасчетыСКонтрагентамиОстатки.Организация КАК Организация,
        ВзаиморасчетыСКонтрагентамиОстатки.Контрагент КАК Контрагент,
        ВзаиморасчетыСКонтрагентамиОстатки.СуммаБухОстаток КАК СуммаБухОстаток
        ПОМЕСТИТЬ ВТ_Начало
        ИЗ
        РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&НачалоНедели, ) КАК ВзаиморасчетыСКонтрагентамиОстатки
        ГДЕ
        ВзаиморасчетыСКонтрагентамиОстатки.СуммаБухОстаток > &СуммаБухОстаток
        И ВзаиморасчетыСКонтрагентамиОстатки.ДоговорКонтрагента.ВидДоговора = &ВидДоговора
        ;
        распиши поподробнее каждый шаг в консоли запроса

      • #35658
        bot_avaOdin — Одинэсник
        Участник

          Димон, привет!

          Твоя задача — выполнить запрос по множеству значений (Организация, Контрагент, Договор) из программной таблицы значений, чтобы не делать запрос к регистру по каждой строке отдельно, а сразу одним запросом с фильтром по всем нужным наборам. Для этого в 1С используется передача таблицы значений как параметра запроса и объединение с ней в запросе.

          Разберу подробно, как это сделать в консоли запросов и в коде:

          ### Шаг 1. Создание программной таблицы значений с нужными полями

          В коде (например, в обработчике кнопки) создаешь ТаблицуЗначений с колонками:

          ТаблицаФильтра = Новый ТаблицаЗначений;
          ТаблицаФильтра.Колонки.Добавить("Организация", Новый ОписаниеТипов("СправочникСсылка.Организации"));
          ТаблицаФильтра.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
          ТаблицаФильтра.Колонки.Добавить("Договор", Новый ОписаниеТипов("СправочникСсылка.ДоговорыКонтрагентов"));
          
          // Заполняешь строки таблицы нужными значениями
          // Например:
          Строка = ТаблицаФильтра.Добавить();
          Строка.Организация = СсылкаНаОрганизацию1;
          Строка.Контрагент = СсылкаНаКонтрагента1;
          Строка.Договор = СсылкаНаДоговор1;
          // Добавляешь столько строк, сколько нужно
          

          ### Шаг 2. Формирование запроса с использованием таблицы значений как параметра

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

          Пример текста запроса:

          ВЫБРАТЬ
            ВТФильтр.Организация КАК Организация,
            ВТФильтр.Контрагент КАК Контрагент,
            ВТФильтр.Договор КАК Договор,
            ВзаиморасчетыОстатки.СуммаБухОстаток КАК СуммаБухОстаток
          ИЗ
            &ТаблицаФильтра КАК ВТФильтр
              ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&НачалоНедели, ) КАК ВзаиморасчетыОстатки
              ПО ВТФильтр.Организация = ВзаиморасчетыОстатки.Организация
                И ВТФильтр.Контрагент = ВзаиморасчетыОстатки.Контрагент
                И ВТФильтр.Договор = ВзаиморасчетыОстатки.ДоговорКонтрагента
          ГДЕ
            ВзаиморасчетыОстатки.СуммаБухОстаток > &СуммаБухОстаток
            И ВзаиморасчетыОстатки.ДоговорКонтрагента.ВидДоговора = &ВидДоговора
          

          ### Шаг 3. Установка параметров и выполнение запроса в коде

          Запрос = Новый Запрос;
          Запрос.Текст = "Текст запроса из шага 2";
          
          Запрос.УстановитьПараметр("ТаблицаФильтра", ТаблицаФильтра);
          Запрос.УстановитьПараметр("НачалоНедели", ДатаНачала);
          Запрос.УстановитьПараметр("СуммаБухОстаток", 0);
          Запрос.УстановитьПараметр("ВидДоговора", СсылкаНаВидДоговора);
          
          Результат = Запрос.Выполнить();
          

          ### Шаг 4. Обработка результата

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

          ### Важные моменты:

          — Таблица значений передается в запрос как параметр `&ТаблицаФильтра`.
          — В запросе создается псевдоним для этой таблицы (например, `ВТФильтр`).
          — Соединение с регистром происходит по всем трем полям.
          — В условии `ГДЕ` можно добавить дополнительные фильтры.
          — Если нужно получить сумму долга по организации, можно добавить группировку по организации и суммировать поле `СуммаБухОстаток`.

          ### Пример с группировкой по организации (если нужна сумма по организации):

          ВЫБРАТЬ
            ВТФильтр.Организация КАК Организация,
            СУММА(ВзаиморасчетыОстатки.СуммаБухОстаток) КАК СуммаДолга
          ИЗ
            &ТаблицаФильтра КАК ВТФильтр
              ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&НачалоНедели, ) КАК ВзаиморасчетыОстатки
              ПО ВТФильтр.Организация = ВзаиморасчетыОстатки.Организация
                И ВТФильтр.Контрагент = ВзаиморасчетыОстатки.Контрагент
                И ВТФильтр.Договор = ВзаиморасчетыОстатки.ДоговорКонтрагента
          ГДЕ
            ВзаиморасчетыОстатки.СуммаБухОстаток > &СуммаБухОстаток
            И ВзаиморасчетыОстатки.ДоговорКонтрагента.ВидДоговора = &ВидДоговора
          СГРУППИРОВАТЬ ПО
            ВТФильтр.Организация
          

          ### Итог

          — Создаешь таблицу значений с нужными наборами Организация+Контрагент+Договор.
          — Передаешь ее в запрос как параметр.
          — В запросе соединяешься с регистром по этим полям.
          — Запрос выполняется один раз, без повторных обращений.
          — Получаешь нужные суммы по организациям.

          Если хочешь, могу помочь с примером полного кода для кнопки.

          Если нужна помощь с конкретным кодом — пиши, помогу.

          Димон, надеюсь, теперь понятно, как сделать запрос с фильтром по таблице значений, чтобы не делать много запросов подряд.

          Дополнение по конфигурации (по индексу конфигурации 1С):

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

          В контексте модуля «УчетВзаиморасчетовОтложенноеПроведение» из конфигурации «СКАТ — Профессионал 5.0» есть подход, который используется для оптимизации запросов с множеством параметров.

          Основные шаги для решения вашей задачи:

          1. **Создание программной таблицы значений с нужными полями**
          Вы создаете таблицу значений с колонками: Организация, Договор, Контрагент. В эту таблицу помещаете все необходимые комбинации.

          2. **Использование временной таблицы в запросе**
          Вместо того, чтобы для каждой строки делать отдельный запрос, вы помещаете вашу таблицу значений во временную таблицу в запросе (через конструкцию `ПОМЕСТИТЬ` или `ВТ_…`).

          3. **Объединение с регистром остатков по ключам**
          В запросе делаете соединение (например, внутреннее или левое) между вашей временной таблицей и регистром остатков по полям Организация, ДоговорКонтрагента, Контрагент.

          4. **Агрегация по организации**
          В запросе группируете данные по Организации и суммируете поле СуммаБухОстаток.

          5. **Передача параметров в запрос**
          Параметры, такие как дата, сумма, вид договора, передаются один раз в запрос.

          Примерный алгоритм в коде (упрощенно):

          // Создаем таблицу значений с колонками Организация, ДоговорКонтрагента, Контрагент
          ТаблицаПараметров = Новый ТаблицаЗначений;
          ТаблицаПараметров.Колонки.Добавить("Организация", Новый ОписаниеТипов("СправочникСсылка.Организации"));
          ТаблицаПараметров.Колонки.Добавить("ДоговорКонтрагента", Новый ОписаниеТипов("СправочникСсылка.ДоговорыКонтрагентов"));
          ТаблицаПараметров.Колонки.Добавить("Контрагент", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
          
          // Заполняем таблицу нужными значениями (ваш код)
          
          // Создаем запрос
          Запрос = Новый Запрос;
          Запрос.УстановитьПараметр("НачалоНедели", НачалоНедели);
          Запрос.УстановитьПараметр("СуммаБухОстаток", 0);
          Запрос.УстановитьПараметр("ВидДоговора", ВидДоговора);
          
          // Помещаем таблицу параметров во временную таблицу запроса
          Запрос.Текст = 
          "ВЫБРАТЬ
          |   ВТ_Параметры.Организация,
          |   ВТ_Параметры.ДоговорКонтрагента,
          |   ВТ_Параметры.Контрагент,
          |   СУММА(Взаиморасчеты.СуммаБухОстаток) КАК СуммаДолга
          |ИЗ
          |   &ТаблицаПараметров КАК ВТ_Параметры
          |   ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(&НачалоНедели, ) КАК Взаиморасчеты
          |       ПО ВТ_Параметры.Организация = Взаиморасчеты.Организация
          |       И ВТ_Параметры.ДоговорКонтрагента = Взаиморасчеты.ДоговорКонтрагента
          |       И ВТ_Параметры.Контрагент = Взаиморасчеты.Контрагент
          |ГДЕ
          |   Взаиморасчеты.СуммаБухОстаток > &СуммаБухОстаток
          |   И Взаиморасчеты.ДоговорКонтрагента.ВидДоговора = &ВидДоговора
          |СГРУППИРОВАТЬ ПО
          |   ВТ_Параметры.Организация,
          |   ВТ_Параметры.ДоговорКонтрагента,
          |   ВТ_Параметры.Контрагент";
          
          // Устанавливаем параметр таблицы
          Запрос.УстановитьПараметр("ТаблицаПараметров", ТаблицаПараметров);
          
          // Выполняем запрос
          Результат = Запрос.Выполнить();
          

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

          Если нужна более подробная помощь с конкретным кодом, пожалуйста, уточните, есть ли у вас уже таблица значений с этими данными и как вы хотите получить итоговую сумму (по организации или по каждой строке). В представленном контексте есть процедуры и функции, которые работают с временными таблицами и оптимизируют запросы, например, `ПодготовитьДоговорыДляРасчетов` и `ПодготовитьОстаткиПоДоговорам`, которые можно использовать как пример.

          Если хотите, могу помочь написать конкретный пример запроса с использованием вашей таблицы значений.

      Просмотр 1 ветки ответов
      • Для ответа в этой теме необходимо авторизоваться.
      База знаний 1С