неділя, 26 березня 2017 р.

Робота з датами в 1С: як порожня дата спричинила зайві привітання

Робота з датами в 1С

Знав би, де впасти, — соломки б підстелив. Народна мудрість.

У практичній роботі розробника в «1С:Підприємство» мені довелося зіткнутися з випадком, який добре показує різницю між незаповненим значенням і NULL. У довіднику «Інформаційні картки» заздалегідь створили приблизно 10 тисяч об'єктів для даних постійних покупців торговельної мережі. На момент інциденту заповненими були близько 7 тисяч карток.

Щоранку одне регламентне завдання знаходило іменинників, а інше надсилало їм SMS із привітанням і запрошенням отримати подарунок у зручному магазині. Запит мав приблизно такий вигляд:

ЗапросИменинников = Новый Запрос;

ЗапросИменинников.Текст = “Выбрать

| ИнформационныеКарты.Ссылка

| ГДЕ

| День(ИнформационныеКарты.ДатаРожденияКлиента) = &День

| И Месяц(ИнформационныеКарты.ДатаРожденияКлиента) = &Месяц”;

Параметри «День» і «Місяць» відповідали поточній даті. Зазвичай відбір знаходив 10–20 людей, іноді до 30. Але 1 січня до нього потрапило майже 3 тисячі карток. На щастя, номери телефонів були лише приблизно у 300 із них.

Чому порожня дата потрапила до вибірки

Для реквізиту типу «Дата» значення за замовчуванням — початок відліку дат: 1 січня 0001 року. Як я тоді пожартував: мабуть, нашої ери, хоча після більш ніж тижня роботи з «1С:Підприємство» вже не був би настільки впевнений. Саме значення дати не тотожне NULL. Тому перевірка лише дня й місяця знаходить і такі незаповнені дати саме 1 січня.

Функція ЗначениеЗаполнено(Дата) для значення за замовчуванням повертає Ложь. Це узгоджується з документацією платформи про незаповнені значення: NULL позначає відсутність значення в певних результатах запиту, тоді як реквізити окремих типів мають власні значення за замовчуванням.

Як виправили відбір

Можна перевіряти заповненість дати під час обробки результатів або відсіювати такі записи безпосередньо в запиті. У початковому випадку запропонували додаткову умову за роком народження:

ЗапросИменинников = Новый Запрос;

ЗапросИменинников.Текст = “Выбрать

| ИнформационныеКарты.Ссылка

| ГДЕ

| День(ИнформационныеКарты.ДатаРожденияКлиента) = &День

| И Месяц(ИнформационныеКарты.ДатаРожденияКлиента) = &Месяц

| И Год(ИнформационныеКарты.ДатаРожденияКлиента) > 1800”;

Межа 1800 тут була практичним фільтром для конкретної клієнтської бази, а не універсальним правилом роботи з датами. Вона також виключає всі дати до цієї межі. Для перевірки саме порожньої дати можна порівнювати поле зі значенням початку відліку; офіційний приклад використовує DATETIME(1, 1, 1, 0, 0, 0). Синтаксис і потрібну умову слід узгодити з мовою запиту та структурою конфігурації.

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

Автор: Віталій Моргун.

Немає коментарів:

Навантажувальне тестування K2 ERP: що перевірити до пікової зміни

Демонстраційна база швидко відкривається, презентація переконлива, а справжня перевірка починається перед відправленням машин: склад проводи...