Довелось столкнуться с такой вот ситуацией: более 10 лет используется конфигурация "Торговля и склад". Очень даже успешно используется, была немного доработана, работает быстро, делает что нужно. В общем, идиллия. Но ничто не длится вечно...
В один "прекрасный" день, а точнее в ночь на первое число как обычно в монопольном режиме попытался открыть период, и вот тебе раз:
Очень даже не вовремя. Первое число выпало на среду, нужно работать, а никак. База довольно большая, поэтому тестирование и исправление не помогло ни в каких вариантах. За первую ночь ничего не решил. Единственным выходом было установить рабочую дату на последний день прошлого месяца и работать таким образом. Здесь необходимо отметить, что этот вариант следует использовать только в качестве крайней меры, так как все сопутствующие документы также придётся заводить этой датой. В первую очередь это касается документов поступления. Чтобы не возникло путаницы, в будущем мы договорились в комментарии документов указывать реальную дату и ручками после решения проблемы вернуть всё на круги своя.
Итак, полумеры были приняты, взялся за дело. Так что же такое за "Error #: -120"? Выяснить не составило особого труда. Эта ошибка возникает, когда размер файла dbf превышает 2Gb. Не буду утверждать на 100%, но это вроде как не только проблема базы данных 1С версии 7.7, но и всех DBF в целом. Отсортировал все файлы в базе данных по размеру и действительно: удивительно, поразительно. Он единственный такой большой, следующий по величине в три раза меньше.
Первым делом посмотрел файл 1Cv7.DD, который содержит описание всех таблиц информационной базы. Оказалось, что это регистр "Книга продаж"
#===============================================================================
#==TABLE no 157 : Регистр КнигаПродаж
# Name |Descr |Type[A/S/U]|DBTableName|ReUsable
T=RG4343 |Регистр КнигаПродаж |A |RG4343 |1
#-----Fields-------
# Name |Descr |Type|Length|Precision
F=PERIOD |Period Registr |D |8 |0
F=SP4336 |(P)КредДокумент |C |13 |0
F=SP4337 |(P)СтавкаНДС |C |9 |0
F=SP4365 |(P)ВидДолга |C |9 |0
F=SP4338 |(P)СуммаНДС |N |16 |2
F=SP4339 |(P)СуммаРуб |N |16 |2
F=SP4340 |(P)СуммаНП |N |16 |2
#----Indexes------
# Name |Descr |Unique|Indexed fields |DBName
I=PROP |PERIOD+PROP |0 |PERIOD,SP4336,SP4337,SP4365 |PROP
#
Первое, что пришло в голову, это ещё раз попробовать сделать тестирование и исправление со следующей комбинацией галок:
При просмотре файла выяснилось следующее: в колонке "Period Registr" стоял 2005 год и записей было очень много, потом 2006, 2007 и так далее. Так как эти записи относились к более ранним периодам, а документы в журнале начинались с 2011 года, соответственно было сделано предположение, что кто-то сворачивал базу, может и неоднократно, но вероятно, немножко кривыми ручками. Предполагалось, что после пересчёта итогов лишние записи уберутся и останется только изящно запустить тестирование и исправление ещё раз, но уже только с одной галкой "Упаковка таблиц информационной базы".
На это была убита ночь со среды на четверг, но к огромному огорчению, к открытию магазина процесс не завершился, пришлось всё останавливать, доставать базу из архива и работать опять на 31 числе прошлого месяца. К сожалению, я не смог придумать никакого способа хотя бы примерно оценить время выполнения данной операции, а в данном случае эта оценка весьма бы пригодилась для принятия решения.
Ситуация начинала уже раздражать. Всегда неприятно ощущать бессилие перед программой. Попросив пользователей ещё денёк поработать на 31 числе на ночь с четверга на пятницу была предпринята попытка свернуть информационную базу за 2 года в надежде сократить размер злополучного файла.
Как только завершился рабочий день, разумеется сделав архив, запустил свёртку базы на 1.01.2013 года, так как документы там были с января 2011 года. Утром с огорчением увидел, что процесс ещё во всю идёт, а уже нужно начинать работать. Опять попросил уже изрядно нервных пользователей потерпеть, и стал думать, ЧТО ЖЕ ДЕЛАТЬ???!!!!
Слава Богу, суббота и воскресенье выходной и соответственно и плечо раззудится, и рука размахнётся. В пятницу после завершения рабочего дня, быстренько сделал архив и снова запустил свёртку на мощном сервере. Но для надёжности взял домой базу, чтобы не класть все яйца в одну корзину.
Пока сервер мощно гонял электроны по многочисленным ядрам своих процессоров и усердно жужжал дисками, свёртывая базу, было решено решить проблему кардинально. Разумеется, было страшно, не натворю ли я дел? Поэтому было решено вспомнить об устройстве этого регистра.
Пришлось порыться в документации. Основное назначение регистра "Книга продаж" — оперативное ведение учета НДС по каждому покупателю. Залез в конфигурацию, просмотрел, как он работает:
Нажал на волшебную кнопочку "Описание" и узнал всё, чо нужно:
Регистр "Книга продаж" предназначен для ведения учета НДС, выставленного
покупателям в расходных документах. Движение приход регистра производится при
проведении документов реализации ТМЦ и услуг покупателям и движение расход - при
включении сумм в книгу продаж (документами "Формирование книги продаж" и
"Запись книги продаж"). По этому регистру производится построение отчета "Книга
продаж".
СТРУКТУРА РЕГИСТРА "КНИГА ПРОДАЖ"
ИЗМЕРЕНИЯ
КредДокумент
Здесь проставляется значение документа, которым были реализованы ТМЦ или услуги
покупателю.
СтавкаНДС
Ставка НДС.
ВидДолга
Вид долга, может принимать значения из перечисления "Виды долга". Практически
означает бухгалтерский счет, на котором ведется учет выставленного покупателю НДС.
РЕСУРСЫ
СуммаРуб
В этом ресурсе ведется учет суммы продаж всего, включая НДС и НП, в валюте
бухгалтерского учета.
СуммаНДС
В этом ресурсе ведется учет суммы НДС продаж, в валюте бухгалтерского учета.
СуммаНП
В этом ресурсе ведется учет суммы НП продаж, в валюте бухгалтерского учета.
РЕКВИЗИТЫ
КодОперации
Код хозяйственной операции движения.
ДокументОплаты
Документ оплаты задолженности. Документ оплаты, по которому произошло
включение в книгу продаж. Проставляется при формировании движения по
включению сумм в книгу продаж.
СтавкаНП
Ставка НП продажи. Проставляется при проведении документов реализации.
Возможно, кому-то это регистр крайне необходим, но похоже, это не наш случай, и я подумал, раз десять лет этот регистр горько не был никому нужен, то и дальше не понадобиться. А что если удалить из него все записи?
А дальше как в песне, "как легко на плоской карте стрелку начертить, а потом идти придётся через горы и овраги....". Нужен был инструмент для выполнения данной операции. Так как я не любитель копаться в dbf, взял то, что подсказал Яндекс. И был это DBF Commander. Обалденная программа, на 20 дней выдаётся бесплатно. Разумеется, можно было взять любую другую, но зачем тратить время, если она позволяет добиться результата. Повторюсь, ни в коем случае не рекламирую эту программу, подойдёт любая, позволяющая удалять записи из DBF и паковать его, даже Visual FoxPro.
Открыл при помощи DBF Commander файл RG4343.DBF, там оказалось почти 25000000 записей!!! Открывался файл минуты три. В меню "Правка" оказался очень удобный пункт "Удалить все записи", им я и воспользовался. Commander жевал файл почти час, уже готов был испугаться, но наконец-то все записи покраснели. Осталось только выбрать следующий пункт "Паковать таблицу".
После этой процедуры файл из многотонного бегемота больше двух гигов превратился в пушинку 257 байт. Не забыв удалить индексный файл RG4343.CDX, запустил программу в монопольном режиме. Индекс моментально перестроился и вышло приглашение открыть новый период.
С замиранием сердца я ждал результат. И вот он сладкий миг победы!!! Период открыт! Причём очень быстро. Попробовал перепровести несколько реализаций, всё хорошо. Они вызывают записи в RG4343.DBF, но с нулями в колонках.
На всякий случай обратился ещё раз к 1Cv7.DD:
#===============================================================================
#==TABLE no 158 : Регистр (Дв.) КнигаПродаж
# Name |Descr |Type[A/S/U]|DBTableName|ReUsable
T=RA4343 |Регистр (Дв.) КнигаПродаж |A |RA4343 |1
#-----Fields-------
# Name |Descr |Type|Length|Precision
F=IDDOC |ID Document's |C |9 |0
F=LINENO |LineNo |N |4 |0
F=ACTNO |Action No |N |6 |0
F=DEBKRED |Flag Debet/Kredit |N |1 |0
F=SP4336 |(P)КредДокумент |C |13 |0
F=SP4337 |(P)СтавкаНДС |C |9 |0
F=SP4365 |(P)ВидДолга |C |9 |0
F=SP4338 |(P)СуммаНДС |N |16 |2
F=SP4339 |(P)СуммаРуб |N |16 |2
F=SP4340 |(P)СуммаНП |N |16 |2
F=SP4341 |(P)КодОперации |C |9 |0
F=SP4342 |(P)ДокументОплаты |C |13 |0
F=SP5345 |(P)СтавкаНП |C |9 |0
#----Indexes------
# Name |Descr |Unique|Indexed fields |DBName
I=IDLINE |of IDDOC+LineN|0 |IDDOC,LINENO,ACTNO |IDLINE
#
Это движения того же самого регистра. Он содержал около 350000 записей. На всякий случай зачистил и его. В результате получил значительное ускорение работы всей базы.
Возможно, у проблемы было и другое решение. Если интересно, давайте обсудим.
Зачем я всё так подробно описал? А потому, что ситуации у всех разные и не нужно, возможно, стрелять из пушки по воробьям. Может, кому-то поможет тестирование и исправление, а может просто прочтение этого материала натолкнёт на спасительную мысль.
Надеюсь, моя статья кому-то поможет.