Технология сравнения с образцом

18.12.11

Разработка - Универсальные функции

Технология для контроля безошибочности изменения алгоритмов проведения

Технология сравнения с образцом

Описываю полезную технологию, которая была применена на практике.

Мы разрабатывали загрузку документов из других баз и формирование по ним проводкам.

Правила были очень сложными и постоянно менялись.

Пользователи боялись, что если мы добавим что-то одно, то как бы не сломали другое.

На вооружение им был дан инструмент проверки, о котором ниже.

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

Через некоторое время мы сравниваем проводки нового загруженного документа со старым документом, и видим разницу, в разрезе до строк документа, т.к. каждая проводка содержит номер строки документа.

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

Пользователи видели, что изменилось в проводках документа со временем в виде отчета:

В отчет выводятся только те строки, в которых есть различия.

Отчет оптимизирован для просмотра в Excel, если значения идентичны, в ячейку выводится только одно значение. Если значения различные, то в ячейке выводится сначала значения из образца, а затем, с новой строки, но в той же ячейке - значение из нового документа (объекта). Ячейки с разными значениями выделяются розовым цветом.

В колонку ошибки выводятся имена колонок с ошибками, таким образом, с помощью автофильтра Excel легко можно отобрать нужные коды ошибок.

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

Кнопка "Сравнить образец" сравнивает текущий образец с документом-объектом.

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

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

Код для превращения документа в образец:

    Если Объект.ЭтоОбразец Тогда        
        Сообщить("Документ уже является образцом, на всякий случай отключим еще раз проводки!", СтатусСообщения.Важное);        
    Иначе        
        Если ЛЕВ(Объект.ИдВнешний, 8) <> "Образец_" Тогда                
            Объект.ИдВнешний = "Образец_" + Объект.ИдВнешний; //Для поиска исходного объекта, достаточно произвольно                
        КонецЕсли;    
    КонецЕсли;

    //Выключаем проводки
    НЗ = Объект.Движения.Основной;
    НЗ.Прочитать();
    НачатьТранзакцию();
    Объект.ЭтоОбразец = истина;
    Объект.Записать();

    //Далее начинаем делать проводки неактивными
    Для Каждого МЗ ИЗ НЗ Цикл        
        МЗ.Активность = ложь;        
    КонецЦикла;

    НЗ.Записать();

    ЗафиксироватьТранзакцию();

 

Отчет можно было бы сделать на СКД (очень хорошо бы сыграло полное соединение по номеру строки), но делать было некогда, поэтому просто сделал на коленке.

Вот код:

Перем Таб, Макет, Колонки;

Процедура КнопкаВыполнитьНажатие(Кнопка)
    Работа();
КонецПроцедуры


Функция СравнитьСтроки(ПроводокСтроки, СтрокаОбъект, СтрокаОбразец)
    флОшибка = ложь;
    Область = Макет.ПолучитьОбласть("Строка");
    Ошибка = "";
    
    Если СтрокаОбъект = Неопределено Тогда
        Ошибка = Ошибка + "ПустойОбъект" + ";";
    КонецЕсли;
    
    Если СтрокаОбразец = Неопределено Тогда
        Ошибка = Ошибка + "ПустойОбразец" + ";";
    КонецЕсли;
    
    Для Каждого Колонка ИЗ Колонки Цикл
        флОшибкаКолонки = ложь;
        Если СтрокаОбъект = Неопределено Тогда
            ЗнОбъект = "-";
            флОшибкаКолонки = истина;
        Иначе
            ЗнОбъект = СтрокаОбъект[Колонка];
        КонецЕсли;
        Если СтрокаОбразец = Неопределено Тогда
            ЗнОбразец = "-";
            флОшибкаКолонки = истина;
        Иначе
            ЗнОбразец = СтрокаОбразец[Колонка];
        КонецЕсли;
        
        Если ЗнОбъект = ЗнОбразец Тогда
            Зн = ЗнОбъект;
        Иначе
            Зн = "" + ЗнОбразец + Символы.ПС + ЗнОбъект;
            флОшибкаКолонки = истина;
        КонецЕсли;
        
        Область.Параметры[Колонка] = Зн;
        
        Если флОшибкаКолонки Тогда
            ИскКолонка = Область.НайтиТекст(Колонка, , , , истина).Лево; //Ячейку целиком
            Область.Область(1, ИскКолонка, 1, ИскКолонка).ЦветФона = WebЦвета.Розовый;
            Ошибка = Ошибка + Колонка + ";";
        Иначе
            //Область.Область(1, ИскКолонка, 1, ИскКолонка).ЦветФона = WebЦвета.Белый;
        КонецЕсли;
        флОшибка = флОшибка ИЛИ флОшибкаКолонки
        КонецЦикла;
    //Область.Параметры.НомерСтрокиДокумента = НомерСтрокиДокумента;
    Область.Параметры.Ошибка = Ошибка;
    
    Если флОшибка Тогда
        Таб.Вывести(Область);
    КонецЕсли;
    
КонецФункции

Функция Работа() Экспорт
    Колонки = Новый Массив();
    Колонки.Добавить("НомерСтрокиДокумента");
    Колонки.Добавить("Период");
    Колонки.Добавить("Сумма");
    Колонки.Добавить("СчетДт");
    Колонки.Добавить("СчетКт");
    Колонки.Добавить("ВалютаДт");
    Колонки.Добавить("ВалютаКт");
    Колонки.Добавить("ВалютнаяСуммаДт");
    Колонки.Добавить("ВалютнаяСуммаКт");
    Колонки.Добавить("КоличествоДт");
    Колонки.Добавить("КоличествоКт");
    Колонки.Добавить("СубконтоДт1");
    Колонки.Добавить("СубконтоКт1");
    Колонки.Добавить("СубконтоДт2");
    Колонки.Добавить("СубконтоКт2");
    Колонки.Добавить("СубконтоДт3");
    Колонки.Добавить("СубконтоКт3");
    Колонки.Добавить("Подразделение");
    
    Макет = ПолучитьМакет("Макет");
    Таб = ЭлементыФормы.ПолеТабличногоДокумента;
    Таб.Очистить();
    Область = Макет.ПолучитьОбласть("Шапка");
    Таб.Вывести(область);
    
    ТЧОбъект = Объект.ПолучитьОбъект().Движения.Основной;
    ТЧОбъект.Прочитать();
    ТЧОбъект = ТЧОбъект.Выгрузить();
    ТЧОбъект.Сортировать("НомерСтрокиДокумента");
    ТЧОбразец = Образец.ПолучитьОбъект().Движения.Основной;
    ТЧОбразец.Прочитать();
    ТЧОбразец = ТЧОбразец.Выгрузить();
    ТЧОбразец.Сортировать("НомерСтрокиДокумента");
    
    ИндОбъект = 0;
    ИндОбразец = 0;
    ПроводокСтроки = 0;
    ПредНомерСтрокиДокумента = 0;
    
    Сч = 0;
    
    Пока истина Цикл
        
        Если Сч % 10 = 0 Тогда
            Состояние("Сравнение: " + Сч);
            ОбработкаПрерыванияПользователя();
        КонецЕсли;
        Сч = Сч + 1;
        
        Если ИндОбъект >= ТЧОбъект.Количество() Тогда
            СтрокаОбъект = Неопределено;
        Иначе
            СтрокаОбъект = ТЧОбъект[ИндОбъект];
        КонецЕсли;
        
        Если ИндОбразец >= ТЧОбразец.Количество() Тогда
            СтрокаОбразец = Неопределено;
        Иначе
            СтрокаОбразец = ТЧОбразец[ИндОбразец];
        КонецЕсли;
        
        //Если строки закончились
        Если СтрокаОбъект = Неопределено И СтрокаОбразец = Неопределено Тогда
            Прервать;
        КонецЕсли;
        
        Если СтрокаОбразец = Неопределено ИЛИ СтрокаОбъект <> Неопределено И СтрокаОбъект.НомерСтрокиДокумента < СтрокаОбразец.НомерСтрокиДокумента Тогда
            СравнитьСтроки(ПроводокСтроки, СтрокаОбъект, Неопределено);
            ИндОбъект = ИндОбъект + 1;
        ИначеЕсли СтрокаОбъект = Неопределено ИЛИ СтрокаОбразец <> Неопределено И СтрокаОбъект.НомерСтрокиДокумента > СтрокаОбразец.НомерСтрокиДокумента Тогда
            СравнитьСтроки(ПроводокСтроки, Неопределено, СтрокаОбразец);
            ИндОбразец = ИндОбразец + 1;
        Иначе // СтрокаОбъект.НомерСтрокиДокумента = СтрокаОбразец.НомерСтрокиДокумента
            Если СтрокаОбъект.НомерСтрокиДокумента <> СтрокаОбразец.НомерСтрокиДокумента Тогда
                Сообщить("Рассинхронизация номеров строк: " + СтрокаОбъект.НомерСтрокиДокумента + " и " + СтрокаОбразец.НомерСтрокиДокумента, СтатусСообщения.Важное);
            КонецЕсли;
            ПроводокСтроки = ПроводокСтроки + 1;
            СравнитьСтроки(ПроводокСтроки, СтрокаОбъект, СтрокаОбразец);
            ИндОбъект = ИндОбъект + 1;
            ИндОбразец = ИндОбразец + 1;
        КонецЕсли;
        
    КонецЦикла;
    
КонецФункции

 

В коде есть интересный момент - каким образом ищется область ячейки для раскраски розовым цветом.

Ну и сам код по параллельному продвижению по двум отсортированным спискам тоже может много где пригодиться.

Вот собственно, и вся технология! Удачи!

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2671    0    John_d    8    

54

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4612    atdonya    22    

45

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3961    ke.92@mail.ru    16    

61

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

28.08.2023    8831    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2077    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16148    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7243    quazare    8    

109
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. luns 21.12.11 13:22 Сейчас в теме
Да. Нужная технология.
Если кому то нужна готовая и проверенная обработка умеющая делать описанное (правда иначе), причем неоднократно проверенная в работе, то вот:

http://infostart.ru/public/15963/
2. fixin 4252 21.12.11 13:59 Сейчас в теме
(1) дада, что-то похожее и лабали, но не такое универсальное. ;-)
3. fomix 33 22.12.11 12:24 Сейчас в теме
Интересно прокатит такой метод, если буду грузить, используя универсальную обработку выгрузки/загрузки XML?
4. fixin 4252 22.12.11 12:42 Сейчас в теме
(3) а сравнивать как будете?
5. fomix 33 22.12.11 12:54 Сейчас в теме
Ну да! Получается что в моем случае образец при загрузке затрется и сравнивать не с чем... Значит не судьба воспользоваться!
6. fixin 4252 22.12.11 14:31 Сейчас в теме
(5) сделайте копию базы и сопоставьте через мою сравнилку баз... правда там движения не сравниваются...
7. fomix 33 22.12.11 14:33 Сейчас в теме
Все равно спасибо за методику! И +
8. JER_MARK 23.12.11 13:20 Сейчас в теме
Частая работа с загрузками привела к мысли о необходимости чего-то подобного. Наработки автора пригодятся.
9. fixin 4252 23.12.11 15:01 Сейчас в теме
(8) мыслите в верном направлении.
(7) пожалуйста, обращайтесь.
10. Модератор раздела 23.12.11 16:06 Сейчас в теме
(0) (1) Аналоги сабжа применяются при тестировании.
У меня в моей разработке Functest.v8 http://infostart.ru/public/15492/
также собираются эти данные и сверяются в довольно удобном виде.
Правда, не так красиво, т.к. ИМХО для тестирования важнее сам факт равенства или отличия.
Оставьте свое сообщение