gifts2017

Бухгалтерские итоги, цикл по субконто, когда количество субконто неизвестно

Опубликовал WWWolfy (WWWolfy) в раздел Программирование - Практика программирования

Перебор всех субконто счёта, когда количество субконто неизвестно, например, заранее неизвестен счёт.

Ниже приведён код, который позволяет пробежаться по всем субконто счёта, когда их количество заранее неизвестно.
Расчёт бухитогов в таких случаях обычно делается так:

БухИт = СоздатьОбъект("БухгалтерскиеИтоги");
БухИт.ИспользоватьСубконто( ,, 1);
БухИт.ИспользоватьСубконто( ,, 1);
БухИт.ИспользоватьСубконто( ,, 1);
БухИт.ВыполнитьЗапрос( начДата, конДата, стрСчета);


Далее проблема в том, что проблематично организовать цикл по неизвестному количеству субконто на счёте. Такой код может вызвать ошибку (если кол-во субконто=1, например):

БухИт.ВыбратьСубконто(1);
Пока БухИт.ПолучитьСубконто(1)=1 Цикл БухИт.ВыбратьСубконто(2);
  Пока БухИт.ПолучитьСубконто(2)=1 Цикл // и т.п. КонецЦикла;
КонецЦикла;


Можно, конечно, сделать рекурсию, но она проблематична, когда есть локальные переменные и их необходимо либо передавать в рекурсию, либо делать общими (для модуля). В результате родился вот такой код перебора субконто:

// Сч - любой счёт, обычно он получен с помощью ВыбратьСчета()/ПолучитьСчет() Сообщить( "Обрабатываем счёт: "+Сч);
КолСубконто = Сч.КоличествоСубконто();
флСтоп=0;
текЦикл = 1; предЦикл =0;
Пока флСтоп=0 Цикл Если КолСубконто=0 Тогда //разок глянем и стоп флСтоп=1;

  Иначе Если предЦикл < текЦикл Тогда //спустились ниже? надо начать выборку БухИт.ВыбратьСубконто(текЦикл);
    КонецЕсли;
    предЦикл = текЦикл;
    флВыбранСубконто = БухИт.ПолучитьСубконто(текЦикл);

    Если флВыбранСубконто = 0 Тогда // если нету, то .. Если текЦикл=1 Тогда // всё, приехали. Конечная. флСтоп=1;
        Прервать;
      КонецЕсли;

      //поднимемся выше, ибо есть куда текЦикл = текЦикл - 1;
      Продолжить;
    КонецЕсли;

    Если текЦикл < КолСубконто Тогда //если получили, то опустимся ниже текЦикл = текЦикл + 1;
      Продолжить;
    КонецЕсли;
  КонецЕсли;

  //итак, выбраны все субконты. Прошу к столу. //тут любой код! Для i=1 По КолСубконто Цикл Сообщить( БухИт.Субконто(i) );
  КонецЦикла;
  Сообщить( "СКК с"+БухИт.СКК("С") + " СКК в"+БухИт.СКК("В") );
  Сообщить( "СКД с"+БухИт.СКД("С") + " СКД в"+БухИт.СКД("В") );
КонецЦикла;


В коде оставлена куча комментариев для удобства понимания, поэтому код выглядит громоздко, на самом деле это не так :)

См. также

Подписаться Добавить вознаграждение
Комментарии
2. Шайехов Алмаз Ольфатович Шайехов (Diamond) 21.01.07 20:42
мдя... проще через рекурсию уж тогда
3. WWWolfy (WWWolfy) 22.01.07 10:51
Через рекурсию тебе придётся шарить все переменные, чтобы они видны были "сверху", либо передевать их через параметры. Здесь же доступ к переменным модуля сохраняется, плюс вывод данных в таблицу проще.
4. Светлана (Bess_Tolkovaia) 23.01.07 13:30
Помнится, в стандартных конфах от Великой и Ужасной 1С (впрочем, может насчет авторя я ошибаюсь?) такая ситуация решается вообще очень прикольным способом. Для каждого варианта количества субконто пишется отдельная ветка.
А предложенный вариант мне нравится. Хотя конечно нужно подумать, чтоб понять.