Остатки на каждый день периода одним запросом — универсальный




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

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

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

<?php // Полная загрузка сервисных книжек, создан 2025-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='\

58 Comments

  1. evgeniti

    декартово произведение вроде бы вполне обходится без конструкций ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПО ИСТИНА

    select

    ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, 3*(a-1)+b-1 ) as megafunction

    , c as nomenkrlatura

    from

    (select 1 as a union select 2 union select 3) as t1,

    (select 1 as b union select 2 union select 3) as t2,

    (select ‘крокодил’ as c union select ‘красный’) as t3

    ——-

    да и если уж на то пошло почему бы не пихать вместо двух одинаковыйх строчек вида (select 1 as a union select 2 union select 3) — таблицу значений с цифрами, сформированную в коде, в качестве параметра

    Reply
  2. Smaylukk

    Потому что изначально поставил себе цель сделать все одним запросом. Если делать табличку с цыферками — то ее перед запросом нужно сформировать, а при реализации на СКД — вообще такого сделать нельзя, только соединив два набора данных — объект (куда собственно таблица попадет) и запрос, но этот вариант уже реализован.

    Что же к Декартовому произведению таблиц — я указал первоисточник, откуда его взял. Можете почитать, почему автор сделал так — просто он делает как раз то, что мне нужно, а далее я не копал

    Reply
  3. Angeros

    А почему было использовано 2 запроса к остаткам, а потом к движениям? Неужели нельзя было обойтись параметром виртуальной таблицы — метод дополнения.

    Reply
  4. Angeros

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

    Reply
  5. Smaylukk

    (3), вполне возможно. Я просто делал этот запрос по аналогии с регистрами сведений, когда из них нужно было получить такую же табличку(курсы валют, цены номенклатуры, …). Просто запрос работает да еще и не очень долго, а я этого и добивался. Если сделаете с методом дополнения с использованием 1 таблички — респект вам 🙂

    Reply
  6. al_zzz

    А запрос точно рабочий? Запускаю в демке по позиции «Петр I Легкие» за период май 2007. При этом получаю в результате, что был на остатки только в последний день периода, хотя по ведомости есть приход от 5 мая 2007.

    Reply
  7. Smaylukk

    Запрос точно рабочий. Текст запроса, при вставке в пост потерял несколько символов. Ну и плюс, таблица дата, которую я выложил имеет ограниченность в 36 символов. Попробуйте скачать сам отчет или поменять разрядность таблицы дат.

    Reply
  8. al_zzz

    (7) Проверил на самом отчете, количество выдает только на последний день периода, если был всего один приход за период.

    Reply
  9. Smaylukk

    (8) al_zzz, извините, не верно понял предыдущий комент. В тексте зпроса я выбираю НачальныйОстаток и соответственно, если был только один приход — в день прихода начальный остаток не изменится. Поменяйте его в тексте запроса на КонечныйОстаток(временная таблица Остатки) и все должно заработать верно.

    Спасибо за выявленную неточность

    Reply
  10. akor77

    Запрос прекрасно работает. Нужно только добавить одно условие для соединения двух таблиц. Иначе даты с остатками будут «обрезаны» по всем товарам. Пошевелите мозгами сами. Я и так хорошо подсказал.

    Автору огромный респект!!!

    Reply
  11. Smaylukk

    (10), спасибо, очень приятно 🙂

    Reply
  12. uri1978

    Отчет точно рабочий?

    Привожу пример. Меняем дату начала и цифры в отчете разные:



    и

    По-моему опечатка в коде.

    Нужно заменить КоличествоНачальныйОстаток на КоличествоКонечныйОстаток. И тогда отчет заработает, остатки совпадут с «Ведомость по товарам организаций». Т.е. нужно:

     ОБЪЕДИНИТЬ ВСЕ
    
    ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(ТоварыНаСкладахОстаткиИОбороты.Период, ДЕНЬ),
    ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
    ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток
    Reply
  13. Smaylukk

    (12), как я уже говорил вот здесь (9), да — я там выбирал начальный остаток. Уже не помню зачем. Спасибо за внимательный анализ:)

    Хотя вот такая заковыка помогает получше узнать структура и принцип запроса

    Reply
  14. uri1978

    Да, действительно не прочитал комментарии. Спасибо за обработку, натолкнула на правильное решение.

    Reply
  15. Smaylukk

    (14), очень рад, что вам пригодилось

    Reply
  16. Smaylukk

    Во второй временной таблице «ТаблицаДата» условие должно быть следующим:


    ГДЕ

    ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) <= &КонецПериода ;

    Последнее убирается при вставке в публикацию.

    Извините

    Reply
  17. petrov_al

    Обратите внимание!!! Запрос корректно отрабатывает не всех ситуациях, например попробуйте например сформировать за период 01.12.2011 по 06.01.2012

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

    Reply
  18. petrov_al

    Анализируйте что выдает конкретно этот подзапрос

    ВЫБРАТЬ

    ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) КАК Дата

    ИЗ

    (ВЫБРАТЬ

    6 * (t1.a — 1) + t2.b — 1 КАК n

    ИЗ

    (ВЫБРАТЬ

    1 КАК a ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6) КАК t1

    ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ

    1 КАК b ОБЪЕДИНИТЬ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВЫБРАТЬ 3 ОБЪЕДИНИТЬ ВЫБРАТЬ 4 ОБЪЕДИНИТЬ ВЫБРАТЬ 5 ОБЪЕДИНИТЬ ВЫБРАТЬ 6) КАК t2

    ПО (ИСТИНА)) КАК t

    ГДЕ

    ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ), ДЕНЬ, t.n) <= &КонецПериода

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

    Дата

    Reply
  19. Smaylukk

    (18) , если вы внимательно читали публикацию — то могли заметить, что в пунтке 2, где я описывал Декартово произведение таблиц — указано, что даный запрос возвращает 36 дней. Запрос вполне рабочий при определенных условиях. Выложен как вариант реализации данной задачи. Все расписано и указаны ссылки первоисточников, так что под свои нужды его очень быстро можно подстроить. Если же вы не в силах это сделать — обращайтесь к специалистам.

    Reply
  20. aspirator23

    Или я не понял, или эта задача решается с использованием СКД.

    Получение остатков на каждую дату решается установкой периода День.

    Reply
  21. Smaylukk

    (20) , возможно и решается. Но основной идеей этой публикации была реализация задачи БЕЗ использования каких-то инструментов кроме запроса.

    Если вам при проведении какого-то документа понадобится данная табличка — вы же не будете СКД туда цеплять 🙂

    Reply
  22. aspirator23

    (21) Согласен, если действительно не нужен отчет.

    Reply
  23. Созинов

    (20) aspirator23,

    не решается, у вас будут остатки не на каждый день. Для этого и выдумывают виртуальную таблицу дат.

    (21)

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

    Еще дополнение — запрос не считает дни, когда товар пришел днем и в этот же день был продан. Я тупо подставил регистр продаж в подзапрос по остаткам 3 объединением. Может кто подскажет как по нормальному сделать подсчет таких дней (утром и вечером нет остатка по товару, остаток только днем)?

    Reply
  24. Smaylukk

    (23) , попробуйте брать НачальныйОстаток + Приход — по идее должно сработать.

    Reply
  25. Гость

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

    Reply
  26. AntonH851

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

    Reply
  27. wildwilduser

    подскажите пожалуйста, может чего недопонимаю

    но вот эта строчка

    МИНИМУМ(ДОБАВИТЬКДАТЕ(ЕСТЬNULL(ОстаткиКонец.НачалоПериода, ДОБАВИТЬКДАТЕ(&КонецПериода, СЕКУНДА, 1)), СЕКУНДА, -1)) КАК КонецПериода
    

    получает конец дня перед ОстаткиКонец.НачалоПериода. это верно?

    я полагаю что должен быть конец дня ОстаткиКонец.НачалоПериода.

    ещё раз возможно что то недопонимаю.

    Reply
  28. Smaylukk

    (27), попробую объяснить:

    • В таблице ОстаткиКонец поле НачалоПериода всегда больше, чем в таблице Остатки.
    • Строка, что вы написали берет минимальную дату, которая больше НачалоПериода в таблице Остатки.
    • Далее, чтобы не было такого, что КонецПериода текущей строки и НачалоПериода следующей не были одинаковы (могут потом быть дублирования) нужно отнять 1 секунду.
    • Ну и последний штрих — для последней записи таблицы уже нет соответствия в таблице ОстаткиКонец, поэтому берем значение параметра &КонецПериода

    Как-то так

    Reply
  29. wildwilduser

    т.е. в таблице ОстаткиПериодами получаем строки двежений, а ДатаНачала и ДатаКонца это даты между движениями по этим позициям?

    Reply
  30. Smaylukk

    (29), Да. И если остаток не менялся за этот период, то мы можем на каждый день в этот промежуток поставить определенное значение.

    Reply
  31. straus

    Касательно объединения в таблице остатков, это необходимо, только на мой взгляд параметр должен быть немного другим:

    РегистрНакопления.ТоварыНаСкладах.Остатки(КОНЕЦПЕРИОДА(&НачалоПериода, ДЕНЬ), ) КАК ТоварыНаСкладахОстатки
    Reply
  32. Smaylukk

    (31), А разве послудеющее объединение

    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, День, , ) КАК ТоварыНаСкладахОстаткиИОбороты
    

    не подтянет эти изменения?

    И вполне возможно, что для учета конечных остатков по дням ваш вариант лучше.

    Но в примере я решил (на свою голову) выбрать начальные остатки по дням, поэтому ваш пример мне не покажет правильной картины, если было движение в в день

    &НачалоПериода

    .

    Спасибо за отзыв

    Reply
  33. straus

    простите за кучу правок, не ожидал, что так быстро ответят. Я пытался получить остатки на начало дня и активно испытывал Ваш запрос.

    тогда нужно совсем удалить объединение с таблицей остатков иначе первой строкой будет остаток именно на начало дня

    Reply
  34. straus

    (32)

    Я получил начальные остатки просто сместив дату в таблице остатков на день вверх, по другому у меня не получилось

    Reply
  35. Smaylukk

    (33) , так ведь начальный остаток и нужен на начало дня :).

    Но если у вас все получилось согласно вашим ожиданиям — тогда все ОК.

    Reply
  36. straus

    так конечный остаток предыдущего дня и есть начальный остаток текущего или я что то не понимаю?

    плюс ко всему, максимум непредсказуемо выберет либо начальный остаток, либо конечный

    Reply
  37. kauksi

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

    Reply
  38. ildarovich

    Не рекомендую эту статью к использованию. Ну не должна такая простая задача выливаться в запрос из более сотни строк! Более правильное в методологическом смысле решение (опирающееся на понимание устройства виртуального регистра остатков) можно найти в публикации Запрос по остаткам регистра накопления на каждый день, а еще более короткое — в моем комментарии к этой же статье.

    Reply
  39. Smaylukk

    Ну сколько нужно повторять? Запрос написан без использования вспомогательных регистров для получения таблицы дат. Наилучшее решение (даже лучше вашего «короткого») — использовать производственный календарь, там точно есть все даты.

    А относительно количества строк — я расширенно показал, как сделать поставленную задачу. И заданием этой статьи было поделиться знаниями. И думаю это понятнее, чем «вот такой запрос, только даты берите там, где у вас каждый день регистр изменяется (не в обиду автора упомянутой публикации)».

    И на своей базе я не могу посмотреть тем запросом остатки на каждый день. Нет у меня такого регистра.

    После этого вы будете утверждать что мой вариант плохой?

    Reply
  40. Smaylukk

    (37) ,что именно нужно поправить?

    Reply
  41. ABudnikov

    Применил этот метод к данным по своим остаткам.

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

    Пример:

    Есть входящий остаток 50 шт. Период построения запроса с 01.09 по 10.09.

    Остаток менялся 05.09 на 45 шт и 08.09 на 30 шт.

    В результате таблица остатков выглядит следующим образом:

    01.09 — 00:00 | 04.09 — 23:59 | 50 шт — верно

    05.09 — 00:00 | 07.09 — 23:59 | 50 шт — не верно ведь остаток на 06.09 должен быть 45 шт

    08.09 — 00:00 | 08.09 — 23:59 | 45 шт — верно

    09.09 — 00:00 | 09.09 — 23:59 | 30 шт — верно

    Reply
  42. Smaylukk

    (41) ABudnikov, в запросе вы берете НачальныйОстаток или КонечныйОстаток? Если брали запрос из публикации — то там Начальный остаток, о чем указано в статье и что соответствует вашим данным.

    Reply
  43. ABudnikov

    (42) беру НачальныйОстаток — так же как и в статье.

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

    Конечный остаток на 05.09 и соответственно начальный на 06.09 у меня 45 шт.

    А в результате работы запроса показывает что на 06.09 50 шт а не 45 шт.

    Reply
  44. Smaylukk

    (43) ABudnikov, не согласен. Запрос в статье все верно показывает. Смотрим на ваш пример, но я немного расширю таблицу:

    Начало периода |Конец периода |Нач. ост.| Оборот|КонОст | Что берет запрос

    01.09 — 00:00 | 04.09 — 23:59 | 50 шт | 0 | 50 шт | 50 шт

    05.09 — 00:00 | 07.09 — 23:59 | 50 шт | -5 | 45 шт | 50 шт

    08.09 — 00:00 | 08.09 — 23:59 | 45 шт | -15 | 30 шт | 45 шт

    09.09 — 00:00 | 09.09 — 23:59 | 30 шт | 0 | 30 шт | 30 шт

    Reply
  45. ABudnikov

    (44) Хорошо а теперь если эту таблицу соединить с таблицей дат, то получается что на начало 06.09 остаток 50 шт, что не является правильным ответом, т.к. 05.09 произошло списание 5 шт

    У Вас в статье написано: «Далее при соединении с таблицей дат, посмотрев в какой интервал остатков входит дата, получаем нужный остаток Главное правильно построить такую таблицу»

    Так вот получается что таблица периодов не отражает всю действительность.

    Reply
  46. Smaylukk

    (45) ABudnikov, ну так выбирайте конечный остаток и будет вам счастье. Почему оно должно показать вам все правильно, если вы выбираете начальный остаток? Виртуальная таблица оборотов дает 4 даты — начало, конец и даты расходов. В день, когда был расход, начальный остаток не изменялся. Это касается 5 и 8 числа. Т.е. в вашей первоначальной таблице и 8 числа должно быть неправильно.

    Reply
  47. ABudnikov

    (46) 🙂 так задача состоит в том, чтоб получить начальные остатки. Да и 8-го тоже не правильный начальный остаток.

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

    Reply
  48. BTRVODKA

    Спасибо, за вашу публикацию!

    Reply
  49. Mails79

    Спасибо.

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

    Сам бы долго соображал что нужно:)

    Reply
  50. bulpi

    Имхо, ошибка в том, что Вы берете начальный остаток, а не конечный. Пример :

    Товар1,

    нач.остаток 01.01.14 — 5 шт, кон.остаток 3 шт.

    нач.остаток 10.01.14 — 3 шт

    У Вас получится, что с 02.01 по 09.01 нач.остаток 5. А на самом деле он 3!

    Reply
  51. Smaylukk

    (50), да, вы правы. С начальными остатками я перемудрил. Не работает. И если честно, то завис — не пойму как сделать 🙂

    Reply
  52. Smaylukk

    (47), да, вы были правы. Только сейчас до этого допер. Спасибо.

    Reply
  53. Aleksey81

    Автор молодец. Очень полезный код выложил. Важно лишь отметить что в том виде, что он изложен можно использовать период не более 36 дней. Ограничение прямо выходит из способа формирования таблицы дат путем «комбинирования» двух массивов по 6 чисел.

    Reply
  54. JorjKrut

    Ребята, вопрос: а чем вам не нравится стандартный механизм дополнения по периоду в итога? А потом выборку из результата запроса обходить с параметрами: ЗапросРезультат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, «ПолеПериод», «ВСЕ»);

    Получаем остатки на каждый день таким образом без лишнего геморроя.)

    Reply
  55. JorjKrut

    Кроме того, если дат не очень много, можно объединять таблицы с последовательным увеличением периода виртуальной таблицы остатков и оборотов на один день. См. пример ниже:

    Функция ПолучитьДанныеОстатки(ПериодОтчета)
    
    МассивДатОтчета   = Новый Массив;
    ДатаВМассив = НачалоДня(ПериодОтчета.ДатаНачала);
    ДатаОкончания = НачалоДня(ПериодОтчета.ДатаОкончания);
    
    Пока ДатаВМассив <= ДатаОкончания Цикл
    МассивДатОтчета .Добавить(ДатаВМассив);
    ДатаВМассив = КонецДня(ДатаВМассив) + 1;
    КонецЦикла;
    РазмерМассиваДат  = МассивДатОтчета.ВГраница();
    ЗапросТекстНачало =    «ВЫБРАТЬ
    | ВЫБОР
    |  КОГДА ТИПЗНАЧЕНИЯ(Добавлено_БанкиКассыПланОстаткиИОбороты.БанкКасса) ТИП(Справочник.Банки)
    |   ТОГДА «»БАНК»»
    |  ИНАЧЕ «»КАССА»»
    | КОНЕЦ КАК БанкИлиКасса,
    | Добавлено_БанкиКассыПланОстаткиИОбороты.Группа КАК Группа,
    | Добавлено_БанкиКассыПланОстаткиИОбороты.БанкКасса КАК БанкКасса,
    | Добавлено_БанкиКассыПланОстаткиИОбороты.РасчетныйСчет КАК РасчетныйСчет,
    | Добавлено_БанкиКассыПланОстаткиИОбороты.Огранизация КАК Огранизация,
    | Добавлено_БанкиКассыПланОстаткиИОбороты.Период КАК ДатаПоЗаявке,
    | Добавлено_БанкиКассыПланОстаткиИОбороты.СуммаНачальныйОстаток КАК СуммаОстатокНачало,
    | Добавлено_БанкиКассыПланОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаОстатокКонец
    |ИЗ
    | РегистрНакопления.Добавлено_БанкиКассыПлан.ОстаткиИОбороты(&НачалоПериода, &НачалоПериода, День, , ) КАК Добавлено_БанкиКассыПланОстаткиИОбороты»;
    ЗапросТекстОбъединить = Символы.ПС + «ОБЪЕДИНИТЬ ВСЕ» + Символы.ПС;
    ЗапросТекстИтоги = Символы.ПС + «ИТОГИ
    | СУММА(СуммаОстатокНачало),
    | СУММА(СуммаОстатокКонец)
    |ПО
    | ОБЩИЕ,
    | БанкИлиКасса,
    | Группа,
    | БанкКасса,
    | РасчетныйСчет,
    | Огранизация,
    | ДатаПоЗаявке»;
    
    ЗапросТекст = ЗапросТекстНачало;
    Для Индекс = 1 По РазмерМассиваДат Цикл
    ЗапросТекстДляДобавления = СтрЗаменить(ЗапросТекстНачало, «&НачалоПериода», «ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, » + Строка(Индекс) + «)»);
    ЗапросТекст = ЗапросТекст + ЗапросТекстОбъединить + ЗапросТекстДляДобавления;
    КонецЦикла;
    ЗапросТекст = ЗапросТекст + ЗапросТекстИтоги;
    
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр(«НачалоПериода», ПериодОтчета.ДатаНачала);
    Запрос.УстановитьПараметр(«КонецПериода», КонецДня(ПериодОтчета.ДатаНачала)+1);
    Запрос.Текст = ЗапросТекст;
    ЗапросРезультат = Запрос.Выполнить();
    Возврат ЗапросРезультат;
    КонецФункции
    

    Показать

    Reply
  56. Smaylukk

    (54) На момент написания публикации этот механизм давал пропуски, если не было движений по регистру. А здесь важно именно видеть остатки на каждый день.

    Как сейчас обстоят дела — не знаю, не мониторил.

    Reply
  57. AndiA
    Reply
  58. vis_tmp

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

    У вас так же?

    Reply

Leave a Comment

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