Универсальная свертка итогов оперативного учета и двигатель регистров




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

65 Comments

  1. skonto

    Поясните комментарий при попытке скачивания «Только спецагенты автоматизации могут скачивать этот файл»

    Reply
  2. support

    🙂 это наше сообщение, сейчас исправим.

    Это значит, что автор разработки поставил ограничение на скачивание файла, и его могут скачать только те, кто разместил на портале свою разработку, и она получила рейтинг не меньше 3.

    Reply
  3. viacht

    Этот файл могут скачивать только те, кто добавил свою программу или статью, и набрал рейтинг выше 3 баллов. Фигня такая вот выскакивает. Кто скачал — поделитесь.

    Reply
  4. sashulyT

    Мне кажется надо более подробно описание написать 🙂

    Reply
  5. KOCMOC™

    Молодца, улыбнуло 🙂

    Reply
  6. poppy

    Снижено требования к скачиванию. Теперь могут скачивать зарегистрированные пользователи.

    Reply
  7. Поражен новизной идеи

    Reply
  8. poppy

    Ничего нового в идее нет. Это скорее классика…

    Reply
  9. CheBurator

    Бяка.

    Я так понимаю, что документы до даты свертки удаляются…?

    Очистка периодики до даты свертки…?

    Есть тонкости в задании например кред.документа для регстра Взаиморасчеты…

    Reply
  10. CheBurator

    Что плохо:

    — навскидку не удалось открыть документ в режиме редактирования.

    — хорошо бы для измерений, которые являются, подчиненными справочникам — светить текстовую колонку Владельца.

    — а почему ограничились 10 измерениями — вдруг у меня — 11?

    итого — бяка…

    Есть более красивое решение по универсальному двигателю регистров

    картинки здесь:

    http://infostart.ru/file.php?0,file=377

    http://infostart.ru/file.php?0,file=378

    http://infostart.ru/file.php?0,file=379

    ..

    по хорошему, конечно, надо было бы влепить -1… за выбранный вариант инструментария, а так, конечно — гуд…

    Reply
  11. CheBurator

    в итоге: пришлось «откатиться» к штатной свертке…

    если ячего не так сдела/понял — просьба меня поюзать…

    Reply
  12. CheBurator

    Нет, все-таки возвернулся…

    +1

    За простоту и эффективность!

    Reply
  13. CheBurator

    Единственное — немного бы ускорил процесс за счет определения первого созданного документа свертки — по определению алгоритма — он лежит в конце дня после сворачиваемых документов, и выборку документов для удаления делал бы ДО ЭТОГО ДОКУМНТА, избежав на каждый удаляемы документ «СЗ.НайтиЗначение»

    Reply
  14. CheBurator

    Процесс немного ускорил, как описал ниже.

    + еще одна бяка: _отображаются_ суммы в документе для ПартииНаличие и Взаиморасчетов покупателей/поставщиков — почему-то без десятичных разрядов (именно отображаются, так как в регистр пишется все что надо)

    Reply
  15. CheBurator

    При этом Банк и Касса — ресурсы показываются как надо — с десятичными разрядами…

    Что скажет автор?

    Reply
  16. CheBurator

    Где-то автор накосячила с процедурой ПриВыбореРегистра()

    Если открывается существующий документ — где происходит назначение типов неопределенным реквизитам ТЧ?

    и попутный вопрос: назначение типа происходит для всего столбца ТЧ дока или только для текущей строки…?

    А?

    Reply
  17. CheBurator

    Да.. обработка требует доработки не надфилем — а драчовым напильником…

    Reply
  18. poppy

    (16) Где-то автор накосячила с процедурой ПриВыбореРегистра()

    В чем конкретно накосячено?

    Назначение происходит при вводе новой строки…

    Reply
  19. poppy

    (14) и (15)

    Ничего не скажу…

    Описанная ситуация не воспроизводится.

    Reply
  20. poppy

    (10)

    > навскидку не удалось открыть документ в режиме редактирования.

    В каком случае?

    > хорошо бы для измерений, которые являются, подчиненными справочникам — светить текстовую колонку Владельца.

    записано как пожелание (© 1С) 😉

    > а почему ограничились 10 измерениями — вдруг у меня — 11?

    В этом есть некий элемент неуниверсальности. Более универсальное решение http://infostart.ru/file.php?0,file=377

    Но, в рамках решаемой задачи:

    — для моего решения проще заполнять документ остатками. Всего три строчки кода:

    Код
          Табл = СоздатьОбъект("ТаблицаЗначений");
          Запрос.Выгрузить(Табл, 1, 0);
          Док.ЗагрузитьТабличнуюЧасть(Табл);
    

    Показать полностью

    — любой программист может легко увеличить рассматриваемое ограничение;

    — более десяти измерений = это скорее нонсенс, чем правило.

    Reply
  21. poppy

    (9)

    > Я так понимаю, что документы до даты свертки удаляются…?

    Помечаются на удаление

    > Очистка периодики до даты свертки…?

    Нет. Надо бы добавить.

    Но в типовых решениях на ОУ редко используются периодические реквизиты, устанавливаемые документами. В этом случае, периодику можно «почистить» другими средствами.

    > Есть тонкости в задании например кред.документа для регстра Взаиморасчеты…

    Напиши подробнее.

    Reply
  22. CheBurator

    (18) Открываем документ ссуществующими строками.

    Вопрос: где происходит назначение формата реквизитов-колонок?

    Reply
  23. CheBurator

    > > Есть тонкости в задании например кред.документа для регстра Взаиморасчеты…

    это из области «доводки», но тем не менее — сворачиваю ОУ, мне не нужны расчеты с клиентами в разрезе кредитных доков (забъем на них!) — просто запишем долг. В этом случае — при проведении дока в измерение кредитного дока будет затолкнуто «пустое» значение — в принципе можно и так, но это считается некомильфово — в типовой Тис в этом случае — в качестве кридитного дока пишется сам документ ввода остатков.

    ..

    ща «куклу» по свертке доделаю — выложу для Типовой Тис с уточнениями, периодикой и прочей шнягой такой как полное удаление истории доков до свертки.

    Reply
  24. CheBurator

    Еще бяка: не проводится контроль ссылочной целостности.

    как пример: возврат покупателю введен на основании реализации с интервалом в полгода. Где-то на этом интервале делаем свертку. В результате — в возврате будет бяка на суммах себестоимости «возвращаемой партии» — так как партия помечена на удаление…

    Reply
  25. poppy

    (22)

    Вот код:

    Код
    Процедура ПриРедактированииНовойСтроки()
       Для ии = 1 по Метаданные.Регистр(СокрЛП(НаимРегистра)).Измерение() Цикл
          Тип = Метаданные.Регистр(СокрЛП(НаимРегистра)).Измерение(ии).Тип;
          Вид = Метаданные.Регистр(СокрЛП(НаимРегистра)).Измерение(ии).Вид;
          Тип = Тип + ?(ПустоеЗначение(Вид) = 1, "", "." + Вид);
          Форма.ПолучитьАтрибут("Измерение" + ии).НазначитьТип(Тип, Метаданные.Регистр(СокрЛП(НаимРегистра)).Измерение(ии).Длина, Метаданные.Регистр(СокрЛП(НаимРегистра)).Измерение(ии).Точность);
          Форма.ПолучитьАтрибут("Измерение" + ии).Доступность(1);
       КонецЦикла;
       Для ии = 1 по Метаданные.Регистр(СокрЛП(НаимРегистра)).Ресурс() Цикл
          Форма.ПолучитьАтрибут("Ресурс" + ии).НазначитьТип("Число", Метаданные.Регистр(СокрЛП(НаимРегистра)).Ресурс(ии).Длина, Метаданные.Регистр(СокрЛП(НаимРегистра)).Ресурс(ии).Точность);
          Форма.ПолучитьАтрибут("Ресурс" + ии).Доступность(1);
       КонецЦикла;
    КонецПроцедуры
    

    Показать полностью

    Reply
  26. poppy

    (23) >это из области "доводки", но тем не менее — сворачиваю ОУ, мне не нужны расчеты с клиентами в разрезе кредитных доков (забъем на них!)

    В результате действий моей обработки регистры остаются в неизменном виде. Поэтому она и называется "Универсальная…".

    С другой стороны в обработке есть код:

    Код
    // Здесь можно указать измерения регистров, по которым детализация в новом периоде не нужна
    Если "Регистр.ПартииТоваров.ПрихДокумент" = "Регистр."+Метаданные.Регистр(и2).Идентификатор+"."+Метаданные.Регистр(и2).Измерение(ии).Идентификатор Тогда
       Продолжить;
    КонецЕсли;
    

    Показать полностью

    Таких конструкций ЕСЛИ может быть несколько. В каждой из них нужно указать регистр+измерение, значения которых не нужны для дальнейшего учета. Вместо них будут пустые значения.

    В качестве развития функционала можно рассматривать следующее.

    Пользователь может редактировать список регистр+измерение интерактивно. Плюс назначать значения по-умолчанию.

    Reply
  27. poppy

    (23) >ща «куклу» по свертке доделаю — выложу для Типовой Тис с уточнениями, периодикой и прочей шнягой такой как полное удаление истории доков до свертки.

    ИМХО тоже самое делает типовая свертка ТиС. Чем она тебя не устраивает?

    Reply
  28. poppy

    (24) > В результате — в возврате будет бяка на суммах себестоимости «возвращаемой партии» — так как партия помечена на удаление…

    Во-первых, рассматриваемая обработка не помечает справочники на удаление.

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

    В-третих, документ «Возврат от покупателя», для расчета себестоимости, использует значения регистра(ов). Как было сказано в (26) регистры не меняются (имеется в виду от даты сверткти+1 и далее) значит действия документа также не изменятся.

    ИМХО ты что-то путаешь.

    Reply
  29. CheBurator

    Сам ты путаешь. Если док-основание возврата от покупателя помечен на удаление — отсутвуют итоги по его партии. себестоимость возвратов тянуть неоткуда…

    Reply
  30. poppy

    (29)

    Док-основание возврата от покупателя — это, как правило, Реализация. Что такое "отсутвуют итоги по его партии" применительно к документу Реализация — не пойму.

    Другое дело, что документ возврата от покупателя, введенный на основании реализации, при своем проведении, использует движения документа-основания. Суть свертки в том, что-бы избавиться от движений документов прошлых периодов.

    В глобальном модуле есть процедура глВыяснитьПартииВозврата(), где определяется себестоимость возвращаемых партий. Там есть условие:

    Код
       Если (ТекДок.ДокОснование.Выбран()=1) и (Свернут=0) Тогда
    

    Показать полностью

    Что-бы "избавиться" от зависимости возврата от движений основания достаточно установить реквизит ФлагСвертки документа-основания, если он имеется, в единицу . Или очистить реквизит ДокОснование самого документа. При этом, партии и их себестоимость нужно перенести в табличную часть документа-возврата. Естественно, нужно учитывать текущее состояние ГП.

    Считаю, что такой алгоритм "пихать" в универсальную обработку = неразумно. Как вариант, можно написать отдельную обработку, которая "подготавливала" бы базу к свертке. Естественно, эта обработка должна быть "заточена" под конкретную базу. Эту обработку заставлять запускать пользователя или подключать ее как плагин.

    Reply
  31. CheBurator

    > Как вариант, можно написать отдельную обработку, которая «подготавливала» бы базу к свертке. Естественно, эта обработка должна быть «заточена» под конкретную базу.

    ..угум, так и подточил в некоторых местах…

    Reply
  32. mihenius

    Попытка это сделать (31)

    http://infostart.ru/projects/1259/

    Reply
  33. CheBurator

    На основе эксплуатации выявлен еще ряд неприятных багов, в первую очередь связанных с работой с измерением, которе задается числом: например: ЦенаПрод в ОстаткахТМЦ и ПартияхНаличие — отображаются на форме докамкриво после открытия дока и манипуляции с ним — дробные части ек…

    Reply
  34. CheBurator

    например, в доке записано цена продажи = 23.80

    на форме !!отражается!! целочисленное значение — при проведении — записывается верный результат…

    где коссяк в отображении — навскидку не нашел…

    Reply
  35. poppy

    (33, 34)

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

    Такое поведение считаю фичей платформы.

    Отображение только целочисленной части числа не замечено. Возможно, это связано с особенностями конкретного релиза платформы (я использую 25-й) или использованием внешних компонент (я не использую).

    Reply
  36. poppy

    Были нарекания при свертке больших баз.

    В версии от 1.02.08 количество строк в создаваемых документах ограничено тысячей.

    Reply
  37. CheBurator

    (35) скинуть базу (урежу до минимума с траблой)?

    Reply
  38. poppy

    (37) Давай

    Reply
  39. Вадимко

    А почему используешь запрос а не выгрузить итоги? 🙂

    Reply
  40. poppy

    (39)

    От этого что-то изменится?

    Reply
  41. Вадимко

    (40) Скорость 🙂

    Если там будет 5-6 группировок… по пухлому регистру…

    Нехорошо конечно пиарить, но посмотри мою обработочку для SQL

    Reply
  42. Вадимко

    (40) Скорость

    Reply
  43. Вадимко

    Сорри… глюкает что-то

    Reply
  44. poppy

    (41)

    2Вадимко

    В моей обработке упор сделан на универсальность и простоту кода.

    Неоспоримым преимуществом является неиспользование ВК.

    Reply
  45. Ёпрст

    Жалко что вариант не совсем рабочий 🙁

    Как и у всех создателей при работе с метаданными есть одна и та же типичная ошибка.

    Reply
  46. Bobak

    (45)Какая ошибка?

    Reply
  47. Ёпрст

    (46) Древняя 🙂

    Для измерений/Реквизитов неопределенного типа будет дырка от бублика…

    тип надобно изначально назначить…

    Reply
  48. poppy

    (47) Пожелание принято. Списибо.

    Reply
  49. Ёпрст

    (48) та не за что, такая же ошибка почти во всех обработках, где копируются реквизиты документов в обход метаданных… все как-то забывают про неопределенный тип данных…потом долго удивляются отсутствием данных:)

    Reply
  50. IsiKosta

    Хорошее и простое решение.

    Однако можно добавить:

    1) в монопольном режиме работает быстрее, поэтому выдать предупреждение о запуске в разделенном режиме, для того чтобы пользователь перезашел;

    2) проверить наличие документа для свертки;

    3) при запуске задать дату свертки (например начало текущего года).

    Reply
  51. poppy

    (50) Спасибо за пожелания.

    Reply
  52. markinleha

    Все понравилось, только поставил удаление документов в транзакцию и добавил пару галок на форму, «свернуть регистры» и «удалить документы», чтобы запускать нужное мне дйствие, ибо метит долго и делает это сразу, быстрее свернуть регистры прибить таблицы движений и потом пометить на удаление.

    Reply
  53. rm123

    Производство+Услуги+Бухгалтерия, редакция 2.8 свернет

    Reply
  54. poppy

    (53) Свернет. Но остатки будут только в регистрах.

    Reply
  55. rm123

    по счетам надо будет ручками остатки вводить?

    как бы его скачать получить?

    Reply
  56. Mixa45

    Я свернул 1С Предприниматель 7.7. Документы помеченные на удаление не удаляются, т.к. ссылаются на созданные регистры. Кто знает что делать?

    Reply
  57. Lucifer_i

    Можно чуток ускорить, если в цикле использовать не «Сообщить()», а «Состояние()». Т.к. «Сообщить()» работает до ужаса медленно. 🙂

    Reply
  58. Andre_ultra

    Спасибо — это в данном случае не то слово. Вам жмут руки огромное число пользователей. Добавил только перенос старых документов по ссылкам из удаляемого периода. Это нужно для того, чтобы база осталась полностью перепроводимой.

    Reply
  59. Energen

    Помогло при свертке базы данных «Торговля и Склад» 9.х, у которой был критический размер файла регистра расчетов с покупателями. Все вроде бы неплохо, но для моей БД, размер которой был около 4 гигабайт, таблицы получились до 40 000 записей, соответственно документ «Двигатель регистров» работает очень не быстро, даже при наличии внешней компоненты. Свертку делал на своем ноутбуке с RAID0 на SSD дисках, т.к. на сервере с двумя Xeon и RAID10 на шести HDD получалось гораздо дольше…

    Автору огромное спасибо!!!

    Reply
  60. nkvg_a

    Спасибо! и ваша обработка сгодилась для свертки комплексной с базой в 3 г

    Reply
  61. corsar4ik

    Поплыли остатки по счетам в комплексной 512.

    Reply
  62. mimos

    Свернул базу Тис размером в 8г -0 теперь размером в 2 гига. Всё нормально, только жалко партии на документ движения не перенеслись. поэтому старые документы удалить не получается. Свернулось всё быстренько и аккуратненько.

    Reply
  63. Sergafan10

    Подскажите пожалуйста, можно ли исправить Вашим документом несписанную (задним числом!) себестоимость, которая возникает при ругани «Не распределилось по партиям…» (пустые партии продают) ???

    Reply
  64. ЛохНесс

    [63]

    Умеючи — можно…

    Reply
  65. niko11s

    Спасибо.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *