Всем, "обрезавшим" огромные базы 7.7 посвящается…




Принцип обмена данными из 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='\

99 Comments

  1. CheBurator

    Приблуда Ромикса позволяет обойти ограничение на размер файла выгрузки

    Reply
  2. Dolly_EV

    Будем знать (на досуге поищу «приблуду Ромикса» или кинь ссылку))

    Только все же лучше не затягивать базу до таких размеров, т.к. «2GB» — это будет просто уже камень на могилку

    Reply
  3. brr

    +1 Отличное решение, вот только эта операция похожа на танец шамана с бубном. напрашивается автоматизация

    Reply
  4. Dolly_EV

    )) точно, бубен местами присутствует :-)) но работы ведутся: пишу разбор файла обмена и автоформирование «обратных» файлов обмена.

    Reply
  5. mihenius

    Плагин romix-a

    http://infostart.ru/projects/1512/

    Reply
  6. romann

    > Если тема интересна — выложу кусок конфиги с документом «Архив».

    Интересна. Как раз сейчас бьюсь с 9Гб базой..

    Кинь на мыло, пжалста: b-a (собака) mail.ru

    Reply
  7. z_serg_v

    Тема интересна. А если без УРБДН? export. import подойдет?Имеется 1 регистр остальной бух итоги. Документы текущего периода надо будет перепровести? Не хотелось бы.

    Reply
  8. Black Romeo

    Наверное если в конфиге основа ТиС то для распределения номенклатуры по партиям(создание партий как при поступлении товара) в ваш «Архив» еще что то надо дописывать?

    Reply
  9. Dolly_EV

    (8) Ничего не надо дописывать. Архив перенесет по регистру «Партии наличие» остатки в разрезе Партий, т.е. ссылки на Спр.Партии сохранятся

    Reply
  10. vova56

    (7) >export. import подойдет?

    Только для простых маленьких баз.

    И вообще — «без УРИБ» здесь не осуждаем.

    А перепроведение оставшихся доков — необходимый этап для окончательной проверки. Идет гладко, если сделали хорошо.

    Dolly_EV, выкладывание куска очень желательно.

    Сочтешь возможным — давай!

    Reply
  11. Dolly_EV

    (10) >Сочтешь возможным — давай!

    объясните ламеру — как этот кусок выложить?))) это надо статью в рубрику «Программы» переместить, или можно как-то здесь?

    или заказывйте на мыло — вышлю

    Reply
  12. Dolly_EV

    А перепроведение доков текущего периода — вовсе не обязательно. Если в точке «обрезки» с остатками все Ок — перепроводить не надо, т.к. доки в текущем периоде с Обменом приедут из старой базы со всеми своими движениями, а «Архив» притащит как раз ссылки на эти движения.

    Reply
  13. Dolly_EV

    Вот: http://infostart.ru/projects/1538/

    положил конфигу

    Reply
  14. vova56

    (13) Спасибо, взял, сделал рабочую базу.

    На одном ПК симулировать распределенку возможно?

    Тут объяснять не обязательно, но если есть ссылки

    на инфу — не скрывайте.

    Reply
  15. vova56

    (14) Пока нашел вот

    http://faq1c.gorbunov.ru/docs-files/index.htm

    Reply
  16. Dolly_EV

    (14) на одном ПК — конечно можно распределенку сделать

    вот еще полезная ссылка http://oksla.narod.ru/urib.htm

    В остальном — спрашивайте конкретно, что не понятно

    Reply
  17. vova56

    (14) «УРБД в 1С77 (пошаговая инструкция)»

    http://kb.mista.ru/article.php?id=3

    Кстати, на примере 1 ПК

    Reply
  18. cs25

    У наших : Центр и 11-ть периферийных … База Аспект (типа ТиСа) чуть-чуть переписанный. Штатная свёртка выдаёт : ладПереноса.Записать();

    {Обработка.ЗавершениеПериода.Форма.Модуль(404)}: Номер не уникальный!

    Как сворачивать — х.з. … 🙁

    Reply
  19. Dolly_EV

    2 sc25 (18): Вообще с вопросом — немножко оффтопик, но решается просто:

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

    Код
    Попытка
        ладПереноса.Записать();
    Исключение
       ладПереноса.УстановитьНовыйКод("_Б");
    КонецПопытки;

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

    Если документ — то ПрисвоитьНовыйНомер()

    А вообще — если в тему — то возьми "Архив" и попробуй свернуть базу по данной метОде ))

    Reply
  20. mihenius

    (18) Пригласите специалиста или почитайте про уникальность номеров

    Решение в (19) или по этим докам временно отключить уникальность …

    Reply
  21. pavel_lucenko

    Зачет.

    Один «-» в справочниках тоже могут быть ссылки на документы (те же партии) про них автор «забыл».

    На счет автоматизации — операция разовая, зачем ее автоматизировать? Это все равно что создавать спец. документ под какую нибудь хитрож.ую операцию совершаемую один раз … иногда бухгалтера требуют 🙁

    Reply
  22. Dolly_EV

    да, про «Спр.Партии» из ТиСа забыл, ибо сам его не юзаю))

    Reply
  23. Dolly_EV

    … но исправляется «на раз»: 3 строки в обработке

    Reply
  24. Dolly_EV

    автоматизировать «перенос» архива и ссылок стоит, если решить проблему «дубляжа» ID объектов при одновременной работе в старой и новой базе, и в дальнейшем «переформировании» Архива в старой и «перезагрузке» его в новую базу с новыми остатками и ссылками. Вот как раз у меня щас остро стоит эта проблема ((( Точнее решение то есть — работать в старой базе не в Центре, а в периферийке, в аналоге которой в новой базе НИКТО НИЧЕГО не создает…Но у меня поезд ушел … документы и справочники насоздавались и там и сям в Центре…

    Reply
  25. ales_good

    Уважаемы автор, вы пишите:

    просто убиваем перед проведением «Архива» 1SUPDTS.DBF и CDX,

    из этого я сдела вывод, что Ваша «старая» база была DBF-ной?

    К SQL-базе есть смысл применять такой алгоритм?

    Reply
  26. Dolly_EV

    (25) в СКЛьной базе убиваем соответствующие таблицы (называются они так же, только «_» перед именем)

    Reply
  27. ales_good

    Ок, все попробовала, эксперимент прошел успешно. Большое спасибо за идею.

    Reply
  28. Dolly_EV

    Я рад!

    Reply
  29. asirius

    Способ многократно ускорить удаление всей кучи документов за период — вернуть взад бухгалтерские итоги (или ТА — для ТИС).

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

    Reply
  30. Dolly_EV

    На SQL все так же работает на ура — проверено 20.04.08- разрезал базу размером почти 20Гб с 7-мью периферийками, на все-про-все ушло 7 часов.

    Еще момент: если режем центральную с периферийными — чтобы потом быстро выгрузить новые периф. базы, достаточно в таблице _1SDBSET значение «C» поля «DBSTATUS» сменить на «N»,

    чтобы осуществить первичную выгрузку в периферийные с ТЕМИ ЖЕ идентификаторами. Старые идентификаторы позволят подгрузить уже в новую базу обмены с перифериек, если,

    например, нет возможностью заменить базы «разом» во всех подразделениях.

    Reply
  31. Кузьмич

    ничо себе в кратце :))

    А как тебе след. вариант: Если у тебя уже есть документ с остатками, то посредством ОЛЕ перенести этот документ с синхронизацией справочников (в пустую базу) из оригинала.

    Как на меня, то быстрее выйдет.;)

    Reply
  32. Dolly_EV

    to 31

    так это надо ПИСАТЬ ПЕРНОС OLE для этого документа! к тому же в моем варианте документ может ПРОВОДИТЬСЯ ТОЛЬКО в Рабочей (где есть остатки) базе

    Как ты «посредством ОЛЕ» перенесешь ДВИЖЕНИЯ РЕГИТРОВ И ПРОВОДКИ документа?!?!

    Reply
  33. vikik

    to 30

    а не могли бы вы поделиться как на SQL очистить таблицы ( DH, DT, RA, RG, 1Cxx,1CUPDTS ). может есть кусок кода, а то унаследовала базу SQL огромных размеров с 10 распределенками, срочно надо ее резать, на dbf умею а на sql не пробовала

    Reply
  34. Dolly_EV

    на SQL — точно так же, УДАЛЯЕМ (не чистим!) полностью нужные таблицы. Именуются таблицы так же, как и файлы в dbf, только в начале знак «_»

    «_1SDBSET » и т.д.

    Найти таблицы можно в след. месте:

    для SQL 2000: «SQL Server Enterprise Manager» — «Databases» — ветка с нашей базой — «Tables»

    для SQL 2005: «SQL Server Management Studio» — дальше так же

    Reply
  35. loomis

    Евгений, Вы могли могли бы связаться со мной по адресу Regmenow2006@yandex.ru есть вопрос по ПУБ

    Reply
  36. sergy77

    Уважаемый Dolly_ev, подскажите начинающему программисту 1с, подойдет ли ваш метод свертки базы через УРБД для самописной конфы на базе упрощенки?

    Reply
  37. Stеls

    Респект за смекалку и знание УРБД!

    Reply
  38. waol

    +за идею, возможно пригодится где нибудь

    Reply
  39. ONDimmON

    Получилось, спасибо!

    Reply
  40. Dolly_EV

    (39) «Регистр «продажи»… » — он скорее всего оборотный 😉

    Reply
  41. Romkono

    Сначала — БОЛЬШОЕ спасибо автору! Идея хороша!

    Решил воспользоваться. Дело дошло до изменения файла выгрузки из «старой центральной» в «новую центральную». Тут всё нормально — файл выгрузки сделал файлом загрузки для центральной, но при загрузке его в «новую центральную» пишет следующее:

    «ПланСчетов.Основной Нарушены правила уникальности кодов справочника ’00’ Код загруженного счета изменен на ‘_00′»

    и такое на каждый бух счёт, который был затронут в документе Архив

    Подскажите, как быть?

    Заранее спасибо!

    Reply
  42. Dolly_EV

    (41) почему-то (не знаю почему ,не разбирался, принял как данность 😉 ) если присутствует компонента «Бух.учет», при выгрузке из Центра в Периферию ВСЕГДА ВЫГРУЖАЕТСЯ ПланСчетов (в файле *.dat блок «{«Accounts»,») ,даже если счета не менялись ни в режиме «Предприятие» ни в режиме «Конфигуратор». А в ответе из Периферии в Центр этот блок («{«Accounts»},») ПУСТОЙ!

    Поэтому, если меняем «направление» файлика — про этот момент не забываем — иначе при загрузке измененного файла якобы периферийной базы в Центр все счета «задвоятся». Проблема кстати решается заменой «испорченного» (с задвоенными счетами) файла 1SACCSEL.DBF на старую копию (это чтобы по-новой не копировать базы и т.д.)

    Reply
  43. Romkono

    СПАСИБО!!! загрузка прошла отлично.

    Reply
  44. Трактор

    Большую распределённую базу так обрезать не получится.

    Вот этой обработкой http://infostart.ru/public/59937/ обрезалась большая распределённая база. Без подпольных ходов.

    Reply
  45. evg300183

    что значит УРБД?

    Reply
  46. Dolly_EV

    (45) компонента «Управление Распределенными Базами Данных» — файл DistrDB.dll в каталоге установки 1С

    вот здесь, например http://www.asd-dnepr.com/urbd/index1.html можно почитать

    Reply
  47. musatov1c.ru

    Большое спасибо, буду знать :))))

    Reply
  48. emptyteam
    dolly_ev пишет:

    Вот: http://infostart.ru/projects/1538/

    положил конфигу

    Большое спасибо, за инструкцию! Сейчас опробую данный метод, о результатах отпишусь.

    Reply
  49. emptyteam

    Нашел ошибку в документе «Архив»

    Пока Рег.ПолучитьДвижение()=1 Цикл

    Для ц=1 по Метаданные.Регистр(й).Измерение() Цикл

    ТипРег = Метаданные.Регистр(й).Измерение(ц).Тип;

    ЗнчРег = Рег.ПолучитьАтрибут(Метаданные.Регистр(й).Измерение(ц).Идентификатор);

    Если флПроверятьМоксель = 1 Тогда

    Если ТЗОбъектов.НайтиСтроку(«индЗначение»,ЗнчРег) <> 0 Тогда

    Продолжить;

    КонецЕсли;

    КонецЕсли;

    Если (фДок=1) и (ТипРег=»Документ») Тогда

    ТЗДок.НоваяСтрока();

    ТЗДок.Док = ЗнчРег;

    ИначеЕсли (фСпр=1) и (ТипРег=»Справочник») Тогда

    ТЗСпр.НоваяСтрока();

    ТЗСпр.Спр = ЗнчРег;

    КонецЕсли;

    КонецЦикла;

    //Зачем по реквизитам ссылки?? по ним НЕТ ОСТАТКОВ!

    Для у=1 по Метаданные.Регистр(й).Реквизит() Цикл

    ТипРег = Метаданные.Регистр(й).Измерение(у).Тип;

    ЗнчРег = Рег.ПолучитьАтрибут(Метаданные.Регистр(й).Измерение(у).Идентификатор);


    Если флПроверятьМоксель = 1 Тогда

    Если ТЗОбъектов.НайтиСтроку(«индЗначение»,ЗнчРег) <> 0 Тогда

    Продолжить;

    КонецЕсли;

    КонецЕсли;

    Если (фДок=1) и (ТипРег=»Документ») Тогда

    ТЗДок.НоваяСтрока();

    ТЗДок.Док = ЗнчРег;

    ИначеЕсли (фСпр=1) и (ТипРег=»Справочник») Тогда

    ТЗСпр.НоваяСтрока();

    ТЗСпр.Спр = ЗнчРег;

    КонецЕсли;

    КонецЦикла;

    КонецЦикла;

    Показать

    Reply
  50. Dolly_EV

    (49) у меня этот кусок заремлен, ибо «//Зачем по реквизитам ссылки?? по ним НЕТ ОСТАТКОВ!» )))

    Reply
  51. emptyteam

    Еще обнаружил ошибку, теперь при формировании бухгалтерских проводок.

    Если субконто у счета 3, то в условии нет кода который формирует данные по 2 субконто и пытается сформировать проводки вот так —

    СформПроводки(тзПров.Субк1,тзПров.Субк2,тзПров.Субк2,тзПров.СНДк,тзПров.СНДс,тзПров.СНКк,тзПров.СНКс);

    Передается Субк2 который всегда равен ПУСТО, а вместо субконто 3 передается Субк2, который еще раз повторюсь всегда равен ПУСТО, т.к. не прописан (при условии что у счета 3 субконто).

    Reply
  52. Dolly_EV
    Reply
  53. Dolly_EV

    (51) Вообще, весь модуль касательно переноса остатков по БУ надо переписать, некрасивый он.

    Reply
  54. emptyteam

    Еще один нюанс, пока не придумал как победить.

    Счет 21, Количество субконто = 2, Кол.=+

    1 Субконто = Номенклатура (учет по количеству, учет по сумме)

    2 Субконто = МестаХранения (учет по количеству)

    При таком раскладе сумма не учитывается

    Например —

    ОбСч.Код = «21»

    П1 = 6512

    П2 = 111747.75

    П3 = 0

    П4 = 0

    БИ.Субконто(1) = Заготовка 1

    ОбСч.Код = «21»

    П1 = 3367

    П2 = 0

    П3 = 0

    П4 = 0

    БИ.Субконто(1) = Заготовка 1

    БИ.Субконто(2) = Склад сырья №1

    ОбСч.Код = «21»

    П1 = 3145

    П2 = 0

    П3 = 0

    П4 = 0

    БИ.Субконто(1) = Заготовка 1

    БИ.Субконто(2) = Склад сырья №2

    Показать

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

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

    Reply
  55. Dolly_EV

    (54) Сорри, сейчас этой темой совсем некогда заниматься!

    Но! в предыдущем посте (52) я положил длинный кусок кода из модуля Архива, который сам правил по ЭТОЙ ЖЕ ПРОБЛЕМЕ весной текущего года:

    Счет 10, Количество субконто = 2, Кол.=+

    1 Субконто = Материалы (учет по количеству, учет по сумме)

    2 Субконто = МестаХранения (учет по количеству)

    В итоге у меня все перенеслось корректно, даже при некорректных остатках на счете! (это когда, например, по Субк1 есть сумма, но по Субк 2 — нет количества, или наоборот)

    А по-хорошему, надо все это в ТЗ собирать как-то хитро, или дописывать и проверять мою «простыню» на предмет всех возможных «грабель» сочетаний свойств счета и субконто: «Количественный», «Суммовой», «ТолькоОбороты». Предпочтительнее конечно собрать в ТЗ

    Reply
  56. emptyteam

    (55) Ой извиняюсь, ступил, я ведь весь код из (52) поста проанализировал, просто не заметил строчку среди комментариев, так как делал анализ через «Сравнить файлы», а там все было в одном цвете.

    //УчетПоСумме = 0, значит делаем проводку по Субк1 — по СУММЕ

    //БЕЗ Количества!

    СформПроводки(тзПров.Субк1,,,0,тзПров.СНДс,0,тзПров.СНКс);

    //и для проводки по Субк2 — ставим ТОЛЬКО Количество

    Большое спасибо за направление.

    Reply
  57. emptyteam

    Еще проблему откопал, счет с единственным субконто и с галочкой «Только обороты»

    Причем это счет 50.1, уж не знаю зачем ему грамотеи поставили галочку «Только обороты»

    Reply
  58. Dolly_EV

    (57) Это не «грамотеи» поставили))) Просто по правилам Бухучета не может быть аналитики с остатками по счету 50 ))) Т.е. Касса — она одна касса, и Кассовая книга печататься должна со сквозной нумерацией по всем денежным документам. У меня в комментариях по этому поводу есть замечание

    Иначе//субконто(1) есть, но остатков по нему нет, или флаг «только обороты» = 1
    //это ИСКЛЮЧЕНИЕ для конфигурации БухТорг —
    //счет 50 — Субконто(2) ДОЛЖНО БЫТЬ на ПЕРВОМ МЕСТЕ!!!
    //Сообщить(«ЧУДО-СЧЕТ! «+Строка(Сч),»!!!»);

    Просто в моей конфиге у счета 50 есть Субконто 2 «Кассы организации», по которому ЕСТЬ остатки (но по методологии БухУчета ТАК ДЕЛАТЬ НЕЛЬЗЯ!!)))

    Поэтому в типовом случае (сч. 50.1, Субконто 1 (об.)Дв. ден. средств)

    после комментария

    //Сообщить(«ЧУДО-СЧЕТ! «+Строка(Сч),»!!!»);
    //СНОВА Второе Субконто! по Метке не получается, ибо прыгать надо внутрь цикла…(((

    для ветки

    Если КолСубк>=2 Тогда

    придется дописать еще вилку (скопировать из чуть ниже):

    Иначе//Субконто 1 без остатка или «только обороты»
    П1=БИ.СНД(«К»);П2=БИ.СНД(«С»);
    П3=БИ.СНК(«К»);П4=БИ.СНК(«С»);
    Если (П1=0) и (П2=0) и (П3=0) и (П4=0) Тогда
    продолжить;
    КонецЕсли;
    СформПроводки(,,,П1,П2,П3,П4);
    Кол=Кол+1;
    

    Показать

    Reply
  59. emptyteam

    (58) Большое спасибо за оперативный и раскрытый ответ, очень ценю.

    У меня еще оказались счета по которым все три субконто «только обороты», сейчас сделаю по аналогии с первым.

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

    ~ЕслиНетСубк3: Если (КолСубк=3) или (флНетСубк3 = 1) Тогда
    Если КолСубк<3 Тогда флНетСубк3 = 0; Перейти ~ЕслиНетСубк3; КонецЕсли;
    //Третье Субконто
    Если БИ.ВыбратьСубконто(3) = 1 Тогда
    //Есть остатки
    Пока БИ.ПолучитьСубконто(3)=1 Цикл
    …………………………………ТЕКСТ ЦИКЛА……..
    КонецЦикла;
    Иначе
    //субконто(3) есть, но остатков по нему нет, или флаг «только обороты» = 1
    //делаем по ветке Иначе для Субконто(2)
    флНетСубк3 = 0;
    Перейти ~ЕслиНетСубк3;
    //СформПроводки(тзПров.Субк1,,,тзПров.СНДк,тзПров.СНДс,тзПров.СНКк,тзПров.СНКс);
    //Кол=Кол+1;
    КонецЕсли;
    

    Показать

    Я пока сделал так

    ~ЕслиНетСубк3: Если (КолСубк=3) и (флНетСубк3 = 1) Тогда
    //Если КолСубк<3 Тогда флНетСубк3 = 0; Перейти ~ЕслиНетСубк3; КонецЕсли;
    Reply
  60. Dolly_EV

    (59) Да вроде нет там «вечного» перехода…

    Заходим в ЕСЛИ по ИЛИ, и дальше Если левая половина=ЛОЖЬ, ДЕЛАЕМ правую половину=ЛОЖЬ, и перенаправляем на ЭТО ЖЕ ЕСЛИ, которое уже заведомо не сработает и попадем на ИНАЧЕ (вообще, цель здесь была — попасть на ИНАЧЕ этой ветки вот таким извращенным способом)))

    Вот раз ты в теме сейчас — сделал бы доброе дело!)))

    ПЕРЕПИШИ весь модуль, кривой он! Лучше перед обходом субконто проанализировать свойства счета и субконто и уже на этом этапе решить чего делать дальше, имхо. А править эту портянку — дело неблагодарное

    Reply
  61. emptyteam

    (60)Уф.. сейчас вроде все переноситься нормально.

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

    В любом случае ОГРОМНОЕ спасибо и за тот код который сейчас выложен, так как он отражает основную идею.

    И большое спасибо за поддержку данной статьи.

    По поводу вечного перехода

    Иначе
    //субконто(3) есть, но остатков по нему нет, или флаг «только обороты» = 1
    //делаем по ветке Иначе для Субконто(2)
    флНетСубк3 = 0;
    Перейти ~ЕслиНетСубк3;
    

    Получается если у нас есть Субконто3, но нет по нему остатков, он переходит сюда «~ЕслиНетСубк3;»

    Там у нас условие

    ~ЕслиНетСубк3:   Если (КолСубк=3) или (флНетСубк3 = 1) Тогда
    Если КолСубк<3   Тогда флНетСубк3 = 0; Перейти ~ЕслиНетСубк3; КонецЕсли;

    Так как стоит оператор «или», а количество субконто у нас 3 (КолСубк=3) и остатков на нем нет, то мы снова попадаем в —

    Иначе
    //субконто(3) есть, но остатков по нему нет, или флаг «только обороты» = 1
    //делаем по ветке Иначе для Субконто(2)
    флНетСубк3 = 0;
    Перейти ~ЕслиНетСубк3;
    
    Reply
  62. Dolly_EV

    Угу. тогда поставить другую метку на «пониже» (ИНАЧЕ для 2-го субконто) и переходить на нее

    Reply
  63. CoverG

    А если документы изменяют периодические реквизиты справочников, как в случаем с амортизацией ОС, то теряется история… Пришлось это самому изменять.

    Reply
  64. Dolly_EV

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

    Reply
  65. *.ru

    Следующий глюк связан с регистрами…

    Для й=1 по Метаданные.Регистр() Цикл
    //только регистры «Остатков»

    Если Метаданные.Регистр(й).ТипРегистра <> «Остатки» Тогда Продолжить; КонецЕсли;

    ИмяРег = Метаданные.Регистр(й).Идентификатор;
    ПолноеИмяРег = Метаданные.Регистр(й).ПолныйИдентификатор();
    РасчРег[й] = СоздатьОбъект(ПолноеИмяРег);
    Если лСписРег.Принадлежит(ИмяРег) = 1 Тогда
    ЕстьРег = 1;
    РасчРег[й].ВременныйРасчет(1);
    КонецЕсли;
    КонецЦикла;
    …
    …
    …
    Для й=1 по Метаданные.Регистр() Цикл
    ИмяРег = Метаданные.Регистр(й).Идентификатор;
    Если лСписРег.Принадлежит(ИмяРег) = 0 Тогда
    продолжить;
    КонецЕсли;

    Показать

    РасчРег[й].ВыбратьИтоги();

    КолДвиж = 0;
    …
    …
    …

    В первом цикле допустим й=5 — регистр оборотов, тогда продолжить и РасчРег[5] — не существует…

    Во втором цикле й=5 имеет место быть и «РасчРег[5].ВыбратьИтоги();» какие, извиняюсь, там итоги…

    Reply
  66. Dolly_EV

    (67) Ну да, список тогда собрать в первом цикле, только участвующих. И второй цикл — по списку пустить, а не по Метаданным.

    Reply
  67. *.ru
    Ну да, список тогда собрать в первом цикле, только участвующих. И второй цикл — по списку пустить, а не по Метаданным.

    А на регистры оборотов просто забить ))

    Reply
  68. Dolly_EV

    (69) Ну хочешь — перенеси «остатки» по регистрам оборотов :-))) Расскажешь потом, что получилось)

    Reply
  69. Dolly_EV

    (69) Вобщем, вставил в Форму, в «ПриОткрытии()», где собирается список регистров на форму, проверку:

    Если Метаданные.Регистр(сч).ТипРегистра <> «Остатки» Тогда Продолжить; КонецЕсли;

    Теперь в модуле проведения можно не проверять на «Остатки» и «й» всегда совпадет

    Reply
  70. *.ru

    (71) И это правильно ))

    PS… кстати попробовал перенести «остатки» по регистру оборотов… не поверишь — переносит(!) обороты за период (указанный в конфе по этому регистру)… вот они, не документированные возможности ))))

    Reply
  71. Dolly_EV

    (72) всмысле? Чем ты попробовал перенести «остатки»? метод ВыбратьИтоги для регистра оборотов вернет 0.

    Reply
  72. *.ru

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

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

    Reply
  73. Dolly_EV

    (74) Хм.. ну я-то тоже проверил, правда типовой нет под рукой, в своей — один регистр оборотный — РасчРег[й].ВыбратьИтоги() = 0.

    Reply
  74. *.ru

    солидарен с хм….

    Reply
  75. gimalaj

    Не совсем понял п.8 про документы текущего периода:

    «8). документы за текущий период так же переносим в «новую» базу через обмен УРБД, проинициализировав (Записать()) документы за нужный период. «.

    Как именно их переносить?

    Reply
  76. Dolly_EV

    (77) Документы надо какой-либо обработкой перезаписать. Примерно так:

    Док=СоздатьОбъект(«Документ»);
    НачатьТранзакцию();
    Док.ВыбратьДокументы(НачДата,КонДата);
    Пока Док.ПолучитьДокумент()=1 Цикл
    Док.Записать();
    КонецЦикла;
    ЗафиксироватьТранзакцию();

    Дальше — выгрузка / загрузка через УРБД

    Reply
  77. gimalaj

    (78) Спасибо за быстрый ответ, я уже сам разобрался 🙂

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

    Перем Субк[3], СпрФ, Сч, РасчРег[30];

    Так вот, нужно предварительно проверить, чтобы размер массива РасчРег[30] был больше общего числа регистров в конфигурации. У меня, как назло, их оказалось 31 🙂

    Reply
  78. Dolly_EV

    (79) Мда.. 31 регистр — это жестоко :-))

    Reply
  79. gimalaj

    Еще одно примечание. Во многих типовых конфигурациях в глобальном модуле при начале работы системы предусмотрено первоначальное заполнение информационной базы (заполняет план счетов и т.д.). Поскольку мы удаляем все, кроме справочников, то конфигурация будет пустой и при первом открытии захочет «самозаполниться», что может внести путаницу в новую базу. В моем случае (Комплексная «Бухгалтерия + Торговля и склад + Зарплата и кадры») — заполнение произошло и загрузка отказалась загружаться. Поэтому перед сверткой рекомендую закомментировать этот участок кода.

    Reply
  80. gimalaj

    Кстати, не разбирались со структурой файла .dat в выгрузке? Как пометить (распровести) переносимые документы в утробе этого файла?

    Reply
  81. Dolly_EV

    (82) Бросил это гиблое дело.. Но чтобы НЕ проведенным документ был — надо чтобы его ДВИЖЕНИЯ в DAT были пустые

    Reply
  82. Dolly_EV

    (82) Выгрузи один и тот же ПРОВЕДЕННЫЙ и НЕПРОВЕДЕННЫЙ док (чтобы ТОЛЬКО он один в выгрузку попал). и сравни

    Reply
  83. AlexBugs

    Делал по этой методике срезку 3 разных баз… Если DBF, то можно с помощью копирования файлов, резко убыстрять процесс срезки (удалить регистры — получили док-ты без движения -> файл переноса гораздо меньше и быстрее грузит их). Какие встретил затыки:

    1. у 1С есть ограничения по объему файла загрузки — где-то 2 Гига,

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

    3. перенос период. реквизитов, изменяемых докуменов приходится обрабатывать отдельно — делать их срезку док-том «Архив».

    4. если регистр очень «грязный» — обычно в Партиях товара много минусов и нулевых остатков, то приходится все это как-то чистить…

    Reply
  84. Dolly_EV

    (85) AlexBugs,

    Если DBF, то можно с помощью копирования файлов, резко убыстрять процесс срезки (удалить регистры — получили док-ты без движения -> файл переноса гораздо меньше и быстрее грузит их).

    А если SQL, то какие проблемы точно также поступить с одноименными таблицами в базе??

    Какие встретил затыки:

    1. у 1С есть ограничения по объему файла загрузки — где-то 2 Гига,

    Ссылка на плагин Romix’a, позволяющий выгружать dat без упаковки в zip, имеет место быть и в статье и в комментариях в начале

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

    ?? Нет ограничений по количеству движений, есть ограничение на >9999 строк в табличной части документа, и то оно связано только с привязкой номера строки к движению регистра (строки с номером > 9999 имеют номер=0).

    в данной метОде документ «Архив» НЕ ИМЕЕТ табличной части

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

    — есть такой грех, Периодику так и не дописал… к вопросу вернусь видимо только через год, пока живем на SQL, растем в размерах, оптимизируем все, что возможно, прямыми запросами, резать базу не собираюсь

    4. если регистр очень «грязный» — обычно в Партиях товара много минусов и нулевых остатков, то приходится все это как-то чистить…

    К сабжу это не относится — или вы предлагаете, чтобы «Архив» еще и автоматом чистил «грязный регистр»?:-)))

    По этому поводу есть очень удобный (в смысле реализации) документ: http://infostart.ru/public/18708/

    Сам им пользуюсь с небольшими допилами. Как раз для «чистки» очень удобен.

    Reply
  85. AlexBugs
    А если SQL, то какие проблемы точно также поступить с одноименными таблицами в базе??

    нужно уметь переносить таблицы из базы в базу, а при DBF копируешь Totall Commanderom и не паришься…

    плагин Romix’a

    пробовал, но счастья не ощутил…

    Нет ограничений по количеству движений

    Пытался перенести цены у 8000 товаров — не удалось, виснет и все… разделил на 2 части и все пошло.

    К сабжу это не относится

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

    Reply
  86. AlexBugs
    Периодику так и не дописал…

    Вот здесь уже решили все проблемы с периодикой 🙂

    http://infostart.ru/public/15219/

    Reply
  87. knight

    А в чем проблемы с периодикой? Разве они не перенесутся вместо со справочниками?

    Reply
  88. Dolly_EV

    (89) Периодические реквизиты, установленные документами (например, документ «Ввод в эксплуатацию ОС» пишет за собой периодику по этим ОС), при удалении этих документов (а они в текущей реализации удалятся, т.к. кроме периодики никаких остатков за собой не оставляют) тоже удалятся.

    Reply
  89. Dolly_EV

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

    Reply
  90. knight

    У нас такого нет. Цены в основном интересуют. Т е периодические реквизиты вводимые вручную. Не с помощью документов.

    Reply
  91. Dolly_EV

    (91) с введенными вручную, не документом — все в порядке. Таблица констант переедет вся в новую базу.

    Reply
  92. knight

    Еще вот такой вопрос. То что остатки вбиваются всегда приходом с + или -. Притом что реальный остаток расход к примеру. Это как то может влиять на работу базы с этими остатками?

    Reply
  93. Dolly_EV

    (94) «Притом что реальный остаток расход к примеру. » — это так имеется ввиду отрицательный остаток?))

    Да не важно + или -. Если был отриц. остаток — он так же с «минусом» и перенесется.

    Reply
  94. Dolly_EV

    (94) Это никак не может «влиять на работу базы с этими остатками»… Остаток — он и в африке остаток… Если его ввести не Приходом, а Расходом с обратным знаком — тоже ничего не изменится

    Reply
  95. knight

    Знак остатка переносится корректно. Но в 1с есть 2 вида движения приход и расход. некоторые отчеты это учитывают. и вот был допустим расход 10 единиц. а стал приход -10 единиц. там есть 2 метода движениеприходвыполнить и движениерасходвыполнить

    Reply
  96. knight

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

    Reply
  97. knight

    Все сделал вроде нормально все. Единственное что удивило свежевыгруженная периферийка из обрезанной базы в 2 раза меньше самой обрезанной.. все же выгружается туда. а файл регистра партии наличие например меньше в 2 раза

    Reply
  98. knight

    Разобрался. Я базу резал заранее на копии. Из копии выгружал док архив(чтоб не удваивать реальные остаки в базе(проводится и распроводится он у нас часов 8)) и документы до 1.09.13. Они уже не редактировались. В базе люди продолжали работать(набивать доки и тд). А на новый год я планировал прогрузить документы с 1.09.13 по 31.12.13. Вроде идея хорошая была меньше заморочек на праздники заранее прогрузить остатки и большую часть доков. В итоге архив затерся, у них там оказывается сквозная нумерация внутренняя для распределенки не зависящая от типа документа. И первый же новый док в базе затер мой архив. Хорошо бэкапил все этапы. Поковырял файлы выгрузки поигрался с id починил. Большое спасибо за обработку очень полезная вещь.

    Reply
  99. Dolly_EV

    (100) Большое пожалуйста )) Но «проводится и распроводится он у нас часов 8» как-то настораживает… Скорее всего «сильно не закрытые» регистры?

    Reply

Leave a Comment

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