Здравствуйте!
Готовы ответить на ваши
вопросы!

Нажимая на кнопку “Перезвоните мне”,
Вы соглашаетесь с Политикой конфиденциальности
и даете согласие на обработку персональных данных

Поиск дублей в регистре накопления

10.08.2015
Время чтения: 5 мин.

1. Что? Где? Когда?

"Дубли в регистре накопления" звучит достаточно бессмысленно.

Надо определиться с этим понятием, а сделать это лучше всего на примере.

Есть РН "Остатки", имеющий для пользователя следующую структуру:

РН «Остатки»


Таким образом, дубли – это запись (или набор записей), отличающиеся только периодом и, может быть, регистратором. В нашем случае набор записей от 17.06.2015 8:24:00 Док2 дублирует набор записей от 16.06.2015 8:03:57 Док1. Маловероятно, но дублей может быть и больше 2.

Собираем статистику по продажам / приходам / расходам / возвратам / перемещениям с торговых точек ежедневно (плюс / минус). Если какой-то приход будет задвоен, то и остатки будут не очень правильные, а для анализа и прогноза это играет важную роль. Заценил масштаб трагедии? (УП)

Записи в РН генерируются при загрузке данных из базы SQL, дублировать такой большой объем в документах нет необходимости. Но нельзя так просто взять и без регистратора сделать запись в РН, Настя! Поэтому мы используем Док. Но раз это аж целый документ, почему бы не хранить более глобальную информацию, такую, как Операция / номер (если не ленивый оператор) / Время. Таким образом, у нас в Док появляется ТЧ "Накладные за смену".

Не загружать Операция Номер накладной Время
1 Нет Приход ФРВЧ0001515 19.07.2015 20:29:13
2 Нет Приход 1516 чуть-чуть ленивый оператор 20.07.2015 2:33:46
3 Нет Приход ооочень ленивый оператор 20.07.2015 2:34:06
4 Нет Перемещение ФРВЧ0001510 20.07.2015 2:34:24
5 Да Приход ФРВЧ0001511 20.07.2015 8:30:20


Да, искать дубли продаж мы не будем и чеки не храним. Мы ж люди. Кто будет есть такой же бутерброд, как сосед по столику "Coca-Cola"? Нам важны такие операции, как приход / расход / перемещения, которые, в свою очередь, тоже могут делиться. Дубль – не обязательно дубль (Евклид). Решение о дубль / не дубль принимает в результате оператор, поэтому не делаем проверку на этапе загрузки.

Хотя… в любом бы случае не делали проверку на этапе загрузки.

Задачу, как смогла, описала.


2. От слов к делу

Блок-схема*:


*Подобие блок-схемы

Основные принципы и решения:

  1. Сравниваем набор с каждым последующим набором, пока не нашли дубль. При этом, если дублей почему-то больше 2, то мы третий из них найдем как дубль второго.
  2. "Нужно сравнивать" необходимо мне, потому что конкретно у меня дубли можно исключить, ориентируясь на номера накладных. Если они есть, конечно.
  3. Итоги именно по времени. По номеру, конечно, более универсально, но его отсутствие влечет за собой большую выборку в один набор, что не соответствует действительности.


3. Не придумала название

Непосредственно к 1С.

Запросом формируем наборы.

‘ВЫБРАТЬ РАЗЛИЧНЫЕ

        |               Док.Ссылка.ТТ КАК ТТ,

        |               Остатки.Операция КАК Операция,

        |               Док.Время КАК Время,

        |               ВЫБОР

        |                              КОГДА Док.Номер = ‘‘‘‘

        |                                              ТОГДА Док.Время

        |                              ИНАЧЕ Док.Номер

        |               КОНЕЦ КАК НомерДубль,

        |               Док.Ссылка КАК ДокДубль,

        |               Остатки.Номенклатура,

        |               Остатки.Количество

        |ИЗ

        |               Документ.Док.Накладные КАК Док

        |                              ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.Остатки КАК Остатки

        |                              ПО Док.Ссылка = Остатки.Регистратор

        |                                              И Док.Время = Остатки.Период

        |ГДЕ

        |               Док.Ссылка.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания

        |               И НЕ Док.НеЗагружать

        |               И Док.Ссылка.Проведен

        |

        |УПОРЯДОЧИТЬ ПО

        |               Дубль

        |ИТОГИ ПО

        |               ТТ,

        |               Операция,

        |               Время,

        |               НомерДубль

        |;’


Пристегнули ремни и поехали по циклам:

Результат = Запрос.ВыполнитьПакет();       

                ВыборкаТорговаяТочка = Результат[0].Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

                Пока ВыборкаТорговаяТочка.Следующий() Цикл    

                               ВыборкаВидОперации = ВыборкаТорговаяТочка.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

                               Пока ВыборкаВидОперации.Следующий() Цикл

                                               ВыборкаВремяНакладной = ВыборкаВидОперации.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

                                               Пока ВыборкаВремяНакладной.Следующий() Цикл

                                                               ВыборкаНакладная = ВыборкаВремяНакладной.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

                                                               Пока ВыборкаНакладная.Следующий() Цикл                                              

                                                                               //ЗДЕСЬ МЫ СОХРАНИМ ПАРУ ДУБЛЕЙ, ЕСЛИ НАЙДЕМ

                                                                               Дубль = новый Структура;

                                                                               Дубль.Вставить(‘ТорговаяТочка’, ВыборкаВидОперации.ТТ);

                                                                               Дубль.Вставить(‘ВидОперации’, ВыборкаВидОперации.Операция);

                                                                               Дубль.Вставить(‘ТекНомер’, );          //Здесь сохраним данные

                                                                               Дубль.Вставить(‘ДокТек,);                 //текущего набора

                                                                              Дубль.Вставить(‘НомерДубль ‘,);     //здесь сохраним данные

                                                                               Дубль.Вставить(‘ДокДубль’,);           //дублирующего набора

                                                                               //А ЗДЕСЬ СОХРАНЯЕМ ТЕКУЩИЙ НАБОР

                                                                               ТекущийНабор = Новый ТаблицаЗначений;

                                                                               ТекущийНабор.Колонки.Добавить(‘Номенклатура’);

                                                                               ТекущийНабор.Колонки.Добавить(‘Количество’);

                                                                               ВыборкаДетальныеЗаписи = ВыборкаНакладная.Выбрать();

                                                                               Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

                                                                                              Строка = ТекущийНабор.Добавить();

                                                                                              ЗаполнитьЗначенияСвойств(Строка, ВыборкаДетальныеЗаписи);

                                                                                              ДокДубль = ВыборкаДетальныеЗаписи.ДокДубль;

                                                                               КонецЦикла;

                                                                               ДубльЕсть = НайтиДубли(ТекущийНабор, ВыборкаВремяНакладной.Время,                                                                                                                          ВыборкаВидОперации, Дубль, ВыборкаНакладная. НомерДубль, ДокДубль);

                                                                               Если ДубльЕсть Тогда

                                                                                              … //Сохраняем куда надо 

                                                                               КонецЕсли;

                                                               КонецЦикла;

                                               КонецЦикла;

                               КонецЦикла;

                КонецЦикла;


И сама процедура поиска:

Функция НайтиДубли(Набор, ВремяНакладной, ВыборкаВидОперации, Дубль, НомерНакладной, ДокДубль)

                ВыборкаВремяНакладной = ВыборкаВидОперации.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

//ТУТ МЫ ПЕРЕСКАКИВАЕМ НА ТЕКУЩИЙ НАБОР, ЧТОБЫ СРАВНИВАТЬ ЕГО СО ВСЕМИ ПОСЛЕДУЮЩИМИ

                ВыборкаВремяНакладной.НайтиСледующий(ВремяНакладной,’Время’);

                Пока ВыборкаВремяНакладной.Следующий() Цикл

                               ВыборкаНакладная = ВыборкаВремяНакладной.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

                               Пока ВыборкаНакладная.Следующий() Цикл

                                               ЭтоДубль = Истина;

                                               Колво = 0;

                                               НомерДубль  =  ВыборкаНакладная.НомерДубль;

                                               ДокДубль = Документы.Док.ПустаяСсылка();

                                               Если НужноИскатьДубль (НомерНакладной, НомерДубль ) Тогда   

                                                               ВыборкаДетальныеЗаписи = ВыборкаНакладная.Выбрать();

                                                               Пока ВыборкаДетальныеЗаписи.Следующий() И ЭтоДубль Цикл

                                                                              Поиск = Новый Структура;

                                                                              Поиск.Вставить(‘Номенклатура’, ВыборкаДетальныеЗаписи.Номенклатура);

                                                                              Поиск.Вставить(‘Количество’, ВыборкаДетальныеЗаписи.Количество);

//В ТЕКУЩЕМ НАБОРЕ ПЫТАЕМСЯ НАЙТИ СТРОКУ ‘НОМЕНКЛАТУРА, КОЛИЧЕСТВО’, ЕСЛИ НЕТ, ТО ЭТО УЖЕ НЕ ДУБЛЬ

                                                                              ЭтоДубль = Набор.НайтиСтроки(Поиск).Количество()>0;

                                                                              Колво = Колво+1;

                                                                                              ДокДубль =  ВыборкаДетальныеЗаписи.ДокДубль;

                                                               КонецЦикла;

                                               Иначе

                                                               ЭтоДубль = Ложь;     

                                               КонецЕсли;

//КОЛИЧЕСТВО СРАВНИВАЕМ, ТАК КАК НАБОР МОЖЕТ СОДЕРЖАТЬ В СЕБЕ ДРУГОЙ НАБОР, НО ДУБЛЯМИ НЕ БЫТЬ

                               Если ЭтоДубль И Колво = Набор.Количество() Тогда

                                               Дубль. НомерДубль =  НомерДубль ;

                                               Дубль. ДокДубль =  ДокДубль;

                                               Дубль. ТекНомер =  НомерНакладной;

                                               Дубль. ДокТек =  ДокДубль;

                                               Возврат Истина;   

                               КонецЕсли;

                               КонецЦикла;

                КонецЦикла;       

                … //Пропускаю за ненадобностью

                Возврат Ложь;

КонецФункции


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

Итоги по "НомерДубль" в блок-схему я не включила намеренно, потому что не заметила их сразу. Этот итог нужен, чтобы сделать проверку "Нужно сравнивать" только один раз. Вообще, если предварительная проверка не нужна, то и итог этот тоже.

В итоге я получила достаточно интересный, хотя и малоприменимый, опыт.



https://1c-ant.ru
(473) 202-20-10

При цитировании статей или заметок
ссылка на сайт автора обязательна
Накопились вопросы и нужна помощь?
С удовольствием на все ответим и поможем всё настроить!
звоните!

Возврат к списку