Байки розробника №1: детективні

Вам не здається, що робота розробника 1С іноді схожа на захоплюючий детективний серіал з непередбачуваним фіналом? Думаю, все відчували цей солодкий момент, коли після довгих блукань у нетрях коду істина нарешті знайдена! Ось і зі мною так було не раз. Пропоную вашій увазі кілька історій на цю тему.

ручний обмін

Кілька років тому, здається в 2014 році, прийшов якось до нас на підтримку новий клієнт.

У клієнта багато баз, багато інтеграцій між ними. База, де ведеться основний облік, за кілька років переписана до невпізнання. Причому в різні моменти її допрацьовували розробники дуже різної кваліфікації. Ніякої документації немає, технічних завдань немає, запитати в разі чого нема в кого. Плюс до всього, спільно з переходом до нас на підтримку відбувався також і переїзд з власних серверів в забугорскій дата-центр (в компанії була реструктуризація), що також додавало неабияку кількість проблем. Все це добро впало до нас одномоментно, практично без будь-яких нормальних процесів приймання-передачі. Загалом, ніколи такого не було, і ось знову!

Клієнт великий, важливий і вимогливий (а є інші?). Починаємо в прискореному порядку в’їжджати в його бізнес-процеси, знайомитися з IT-службою, налаштовувати сервера, обробляти заявки. Раптом, в якийсь момент встає обмін між двома найголовнішими, найважливішими інформаційними базами. Обмін повністю самопісний. Ніяких вам універсальних механізмів, правил обміну, EnterpriceData або чогось подібного. З однієї бази COM-му чіпляємося в іншу базу, збираємо дані і погнали. Тільки код, тільки Hardcore!

Отже, обмін не працює. Помилка абсолютно незрозуміла і незрозуміла: «в даній транзакції вже відбувалися помилки». ОК, вже відбувалися, зрозуміло, вірніше – не зрозуміло, далі що?

Гаразд, відкриваю конфигуратор в бойовій базі (немає часу збирати якісь тестові стенди), ставлю точки зупину, запускаю обмін. Виявив процедуру, де виникає помилка. Вже добре. У цій процедурі також ставлю крапку зупинки і йду через підрядник по F10. Намагаюся вже тут виловити злощасну рядок, де всі падає, і … обмін проходить без помилок. Що за чортівня? Але часу розбиратися немає. Відписувався клієнту, що обмін прогрузити, і їдемо далі розрулювати заявки.

Але на наступний день (обмін ходив раз на добу вночі) все знову повторюється. Регламентне завдання не відпрацьована. Та ж помилка. Знову конфигуратор, знову точки зупину, F10, і знову обмін проходить без помилок.

Ближче до вечора розгортаю тестові бази на потрібну дату. Запускаю обмін – помилка! Ставлю в конфігураторі режим «Зупинка помилково». Помилка є, зупинки немає! Іду отладчиком через підрядник – немає помилок! Починаю вірити в магію і паралельні світи. Їду додому, багато думаю.

Наступний день вже знайоме починається з того, що вночі обмін не пройшов. Треба розуміти, що все це відбувалося в режимі авралу. Сидіти кілька годин із завданням немає ніякої можливості. В результаті склали розклад: щоранку черговий розробник відкривав робочий конфігуратор і проганяв обмін руками в режимі налагодження. Це тривало кілька тижнів, поки не розгребли більш термінові завдання і не змогли зайнятися цією проблемою детально.

Причина ж виявилася в наступному: в процесі обміну йшла запис деяких службових даних в певний службовий регістр, причому регістр був періодичний з періодом в 1 секунду. Коли обмін запускався регламентним завданням, відбувався запис в цей регістр однакових даних, відповідно обмін падав з помилкою «запис не унікальна». Коли йшли налагодженням, між ітераціями проходило більше однієї секунди і все службові дані записувалися в регістр без помилок. Зупинка помилково не спрацьовувала, тому що як весь обмін був написаний «в спробі», а до цього моменту у вищій процедурі також була виняткова ситуація, яка на результат обміну не впливала, але не давала відловити помилку записи в регістр (привіт розробнику, який це написав).

Виникає питання, чому ж раніше все працювало? А пам’ятаєте про переїзд в дата-центр? Раніше сервера були старі, повільні і ситуацій записи в регістр в рамках однієї секунди не виникало. А нові сервера працювали так швидко, що між ітераціями циклу (де і був запис) проходило менше секунди.

Магія тут виявилася ні при чому. Винні гигагерци.

Вантажимо вантажимо вантажимо залишки

Впроваджували ми якось 1С: ERP в одній великій торговельній мережі.

Ще на самому початку проекту з’явилася задача по завантаженню залишків (куди ж без неї?) З діючої системи замовника (НЕ 1С). Як формат передачі даних вибрали Excel, т. К. В цьому випадку не була потрібна доробка вихідної системи.

Підсумкова завдання зводилося до наступного: необхідно було прочитати файл із залишками, отримані дані розпізнати, потім згорнути рядки по набору полів «Організація, Склад, Підрозділ, Номенклатура, Характеристика і т. Д.» З підсумовуванням кількості і вартості. Далі, для кожного набору «Організація, Підрозділ, Склад» створювався окремий документ «Введення початкових залишків» із заповненням табличній частині. Причому для простоти тестування і налагодження, а також щоб не плодити зайві документи при кожному завантаженні одного і того ж файлу, існуючі документи, що відповідають параметрам пошуку, перезаписувати. На формі обробки була відповідна «галочка». Загалом, все як завжди.

Написав обробку, її протестували на тестових прикладах. Все працює.

Ближче до старту, клієнт почав поступово скидати файли з залишками для завантаження. Консультант вантажить, документи створюються, все добре.

Звіряємо підсумок в 1С з першоджерелом – не сходиться. Клієнт вивантажує файли Excel ще раз, запевняє, що файли створені правильно. Консультант вантажить файли, звіряє кожен файл, все завантажується вірно. Загальний результат все одно не сходиться. Файли величезні (загальний обсяг під 200000 рядків), вантажаться довго. Пошук помилки затягується. Старт під загрозою, завдання отримує найвищий пріоритет. Кожна ланка ланцюга працює без помилок, але залишки у двох системах ніяк не хочуть зійтися.

Як часто буває, причина лежала на поверхні, але її чомусь відразу ніхто не побачив. Справа в тому, що клієнт надав кілька файлів із залишками. І в різних файлах існували рядки з однаковими наборами «Організація, Підрозділ, Склад» (і навіть з однаковою номенклатурою). Відповідно, слідуючи алгоритму, обробка завантаження пересоздавал деякі документи, які були створені раніше при завантаженні даних з інших файлів.

Завантажили файли з невеликим зсувом у часі (пошук відбувався також і за датою документа) і залишки зійшлися.

Широка страна моя родная

«Зарплата і управління персоналом» версії 2.5. РИБ на 11 баз. Кожна філія працює в своїй базі, підсумкові дані зливаються в центральний офіс.

Тільки що впроваджений новий функціонал – дуже хитрий і складний розрахунок оплати понаднормових годин.

Приходить заявка – дані розрахунку переробок по одному співробітнику розрахувалися неправильно.

Конфігуратор, налагодження, отримую підсумковий запит, консоль запитів, вставлю в потрібні місця фільтри по співробітнику, виконую, отримую результат. Розписую, як і чому отримані суми, віддаю завдання. По всьому виходить, що все розраховано вірно.

Консультант зв’язується з клієнтом. Разом вирішують, що так, все вірно. Але незабаром завдання повертається: у філії при розрахунку суми інші. Так. Вже цікавіше.

Ми розробляємо на серверах центрального офісу, все розроблювальні / тестові є копією центральної. З обмінами вже давно ніяких проблем не було.

Підключаюся до бази філії, роблю розрахунок, дійсно, по одному співробітнику дані не сходяться з центром. Консоль запитів, фільтр по співробітнику – результат інший. Хм … Очевидно, справа в відрізняються вихідних даних. Але де саме?

Як я говорив, алгоритм розрахунку нетривіальний, запит під дві тисячі рядків, купа таблиць (у загальному, як зазвичай і буває в ЗУП). Починаю плавно підніматися по запиту знизу-вгору, порівнюючи значення тимчасових таблиць. Десь в середині запиту знаходжу таблицю, з якої починаються невідповідності. Йду далі і натикаюся на регістр, помилку в якому я зовсім не очікував …

Справа в тому, що ця філія знаходиться в Казані. А в Татарстані є національне свято з плаваючою датою – «Курбан-байрам», який в 2016 році випав на 12 вересня. Відповідно, в виробничому календарі це був вихідний день, і робота в цей день вважалася переробкою. А в центральній базі, де був загальний Російський виробничий календар – це робочий день.

Описую всю ситуацію. Віддаю завдання консультанту. Консультант дзвонить клієнтові. Десь в глибині душі починає зароджуватися дуже недобре передчуття.

Ссылка на основную публикацию