Продолжение разговора о мусоре в модулях VBA начатого в статье “Модуль для очистки от мусора и исправления других модулей”
Автор: Юрий Шерман www.tour-soft.com О мусоре в модулях Access и крахе проектов VBA. Большая благодарность Сергею Гаврилову и Дмитрию Шилкину(ДиД). Без их ценных материалов статья была бы значительно менее информативной. В документации от Microsoft вы не найдете ни упоминаний о мусоре в модулях VBA, ни предупреждения о возможности неожиданного разрушения (краха) проекта. Понятно почему. Ведь то и другое - ошибки или недоработки MS. Почти во всей обширной литературе, посвященной MS Access, так же нет упоминаний о них. Приятным исключением является "Access 2000" К. Гетца. Но и там упоминается только возможность краха проекта. О мусоре - ничего. А на практике программисты, использующие MS Access, могут встречаться с мусором ежедневно, ничего о нем не зная. О возможности краха узнают, когда он уже случится. В статье изложено текущее понимание автором причин этих явлений и способов борьбы с ними. Статья построена на опыте работы с А-1997 и А-2000. Автор будет благодарен за любые материалы, дополняющие или опровергающие утверждения статьи. В особенности об их верности в отношении А-2002. Что такое мусор в модулях Access. Известно, что Access при удалении каких-либо объектов базы только помечает их как удаленные, реально не удаляя их из файла. Это часто приводит к быстрому росту размера базы. Для реального удаления помеченных объектов предусмотрена утилита сжатия базы. Другим средством сжатия является полный импорт базы в предварительно созданную пустую базу. Часто после импорта размер базы становится меньше, чем после сжатия. Обратных случаев не наблюдалось. То есть импорт - более действенное средство, чем сжатие. Кроме того, импорт может выявить испорченные структуры базы и во многих случаях их исправить. Однако импорт подразумевает наличие прав на его проведение, выполняется несколько сложнее и дольше. Потому импортом пользуются в основном программисты - разработчики базы. Регулярно проводя сжатие/импорт базы, программист надеется, что база имеет реальный размер и не содержит ненужной (мусорной) информации. Для баз, не содержащих модулей VBA, это действительно так. Однако применив для баз, содержащих модули, другие средства очистки, описанные ниже, нередко можно убедиться в том, что мусор в них есть. Более того, наблюдались случаи, когда большая часть базы состояла из мусора. Окончательно сформулируем: под мусором в модулях Access понимается ненужная информация, не удаляемая из базы методами сжатия/импорта. Как появляется мусор? Если бы имелся точный ответ на этот вопрос, то этой статьи бы не было. Очевидно, что появление мусора связано с недоработками в самом Access. И, если бы была известна причина его появления, то он был бы устранен. Но мусор точно наблюдался в версиях Access от А-2 до А-2000. И устранен не был. Вопрос о наличии мусора в А-2002 открыт. Все попытки автора получить мусор в базе несложной структуры с помощью фиксированной последовательности действий окончились неудачей. Однако в первом варианте базы, приведенной в примере к статье "Простая работа с MS WORD" и состоящей из одной формы и одного общего модуля, из 460 Кб оказалось 130 Кб мусора. То есть он появляется и в базах простой структуры. Так как экспериментами выяснить ничего не удалось, то соображения о причинах появления мусора носят характер предположений. Если вы проведете полную компиляцию проекта VBA, то для каждого исходного модуля будет создан его Р-код. Именно он выполняется (интерпретируется) при запуске базы. При запуске не компилированного проекта создается временный Р-код, который исполняется, но не сохраняется в базе. Так же, создавая временный Р-код для процедуры, получившей управление, Access работает и в режиме отладки, когда вы запускаете на исполнение только что откорректированный вами исходный текст. Предположим, что вы откомпилировали проект полностью, а затем откорректировали и сохранили один их модулей. Текст модуля будет внесен базу заново, а старый текст будет помечен, как подлежащий удалению. Кроме того будет помечен "к удалению" старый Р-код модуля. Р-коды остальных модулей останутся без изменений. При новой компиляции будет создан новый Р-код для откорректированного модуля. При сжатии базы отмеченные части будут удалены. Все это можно наблюдать, следя за размером базы на разных стадиях проведения перечисленных работ. Эта простая схема теоретически не оставляет места для появления мусора. По идее, полная компиляция проекта должна привести к удалению всех ненужных Р-кодов. Но это происходит не всегда. Michael Kaplan на конференции comp.databases.ms-access утверждает, что в действительности Access имеет 11 различных уровней компиляции. Содержание этих уровней Каплан не раскрывает. Копию его ответа можно найти по адресу http://www.trigeminal.com/usenet/usenet004.asp?1049. Если допустить появление каких-либо ситуациях ненужных Р-кодов, но не отмеченных, как подлежащих удалению, то они и будут мусором. Это могут быть Р-коды, находящиеся в частичном использовании (следуя Каплану), или Р-коды, которые Access "забывает" отметить как ненужные. Очень похоже, что одной из ситуаций, при которой возникает мусор, является корректировка процедур во время их исполнения. Другой подозрительной ситуацией является копирование собственных процедур и последующая корректировка копий. Неоднократно при компиляции выдавалось сообщение о дублировании имен процедур, хотя имя процедуры после копирования было изменено. После перезагрузки Access сообщение исчезало. Можно точно утверждать, что именно Р-коды, частично или полностью не используемые, но не помеченные "к удалению", являются мусором. Но доказательством этому являются не подозрения, указанные выше, а эффективность методов удаления мусора, сводящихся к общей пометке всех Р-кодов как подлежащих удалению. О неожиданном разрушении (крахе) проектов VBA. Сообщений на эту тему значительно больше. От упомянутого выше ответа Каплана, до К. Гетца и Microsoft knowledge base (ACC97: How to Repair a Damaged Jet 3.5 Database (Q279334) http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q279334. Внешний вид краха может быть различным: от сообщения Access об синтаксической ошибке в строке, где её явно нет, до сообщения Windows о выполнении Access-ом недопустимой операции и немедленном его закрытии. Крах базы каким-то образом связан с мусором. На этот раз, видимо, мусором некорректным и влияющим на работу интерпретатора. При регулярном проведении операций по очистке модулей от мусора и импортировании базы (импорт исправляет нарушения в других объектах базы, прежде всего в формах) ситуации краха не наблюдалось в большой базе в течении 2-х лет. Хотя база корректировалась почти ежедневно. При крахе базы для её восстановления нужно использовать те же методы, что и при очистке от мусора. Однако имеются сообщения о таком крахе, когда импорт объектов уже не работает. Здесь может спасти только резервная копия базы. Поэтому совет: не приступайте к корректировке базы, пока не сделали ее копию. Рекомендуется также делать копии в процессе корректировки, если она большого объема. Методы очистки базы от мусора и восстановления после краха. Параметр /decompile. По сообщению Каплана, недокументированный параметр командной строки /decompile используется Microsoft при работе с бета-версиями Access. В этом же причина его недокументированности. Исполнение /decompile приводит к снятию флагов компилированности со всех модулей базы. Применение параметра описано в указанной выше Microsoft knowledge base. Там же рекомендуется немедленное проведение полной компиляции базы после применения параметра. Рекомендация, к сожалению, не всегда исполнима, так как в модулях могут содержаться синтаксические ошибки. К. Гетц в первом томе "Access 2000" дает другой, ещё более жесткий порядок использования параметра. Цитата: "В предыдущих версиях Аксесс при большом размере базы данных проект VBA мог неожиданно оказаться разрушенным. Мы еще не выяснили, случается ли такое в Аксесс 2000, но вам лучше знать о возможности такой ситуации. Если, работая с большим приложением, вы обнаружите, что VBA ведет себя странно, попробуйте воспользоваться недокументированной опцией командной строки /decompile. Однако сначала обязательно сделайте резервную копию своего приложения. Затем запустите Аксесс из командной строки, открыв базу данных с флагом /decompile, вот так: "MSACCESS ВашаБазаДанны.mdb /decompile". Аксесс загрузится, отроет базу данных и сбросит флаги компиляции проекта. Сохраните базу данных и закройте Аксесс. Снова загрузите Аксесс уже обычным путем, откройте базу данных и тут же откомпилируйте проект. Снова закройте базу данных и перезапустите Аксесс. Теперь база данных должна быть "чистой" и готовой к работе."" Каплан говорит вообще о риске применения параметра. Он советует применять этот параметр только тогда, когда реально состоялся крах проекта. Профилактическое его применение, по мнению Каплана, может привести к порче вполне работоспособной базы. Все это вместе заставляет относиться к применению /decompile с достаточной долей опасения. В качестве альтернативы предлагается метод очистки модулей от мусора и восстановления базы после краха с помощью перезаписи модулей. Перезапись модулей. Если вы удалите модуль из базы, предварительно скопировав его текст в ClipBoard, то Access все Р-коды, связанные с модулем, пометит как подлежащие удалению. Если вы затем создадите новый модуль под старым названием, и вставите в него текст из ClipBoard, то Access не свяжет этот модуль со старыми Р-кодами. Последовательно применяя эту операцию ко всем модулям базы вы достигните того же эффекта, который дает параметр /decompile. Но, как показывает практика, без его ограничений. То есть вы можете исполнять эту операцию произвольное количество раз и в любое время, не опасаясь испортить базу. После перезаписи модулей вы можете компилировать и сжимать базу в любом порядке. Ограничений нет. Более того, имеются сообщения о случаях, когда перезапись помогает, а параметр /decompile бессилен. Процесс перезаписи модулей можно выполнить программно. В статье “Модуль для очистки от мусора и исправления других модулей” приводится текст модуля, выполняющего эту перезапись. В качестве места временного хранения текстов он использует не ClipBoard, а временный файл на диске. Этот модуль можно включить в состав основных модулей вашей базы или оформить как ADD-In. Следует отметить, что в модуле используются только документированные возможности Access. Заключение. Подводя итоги, можно дать следующие рекомендации, позволяющие предупредить крах базы программ и освобождающие её от мусора. Следует: - создавать резервные копии базы, храня 5-10 предшествующих вариантов; - регулярно проводить очистку базы с помощью CLearModules; - регулярно восстанавливать базу методом импорта. Следует применять так же сжатие базы. Но оно носит вспомогательный характер. Например, после завершающей общей компиляции сжатие уменьшит общий размер базы. Юрий Шерман Просмотров: 14024
Ваш коментарий будет первым | | |