Страницы: 1
RSS
Как реализовать автоматический импорт-экспорт макросов в книге.
 
Добрый день.
Суть проблемы такова.

Есть три параллельных проекта. В этих  проектах есть задачи, которые решаются одинаковыми методами. Для реализации этих "универсальных" методов я (пока) выделил 8 модулей  :( , которые используются в разных комбинациях, но должны быть одинаковы во всех проектах. Эти модули постоянно дорабатываются.
И чтобы многкртано не писать один и тот-же код, сейчас я  в ручную синхронизирую все модули (в конце работы - экспорт в файлы, в начале работы - импорт). Хранить все модули в личной книге макросов - не вариант по двум причинам:
   1. Все проекты реализуются на разных компах.
   2. После завершения проект должен быть  полностью автономен: клиент будет тягать его с собой на флешке и работать где придется. (Проблема работоспособности на  Excel разных версий это отдельный геморрой  :) ).

Сам процесс "импорт-экспорт" - это тупя, нудная, длительная и неудобная работа, критичная к ошибкам. Я пару раз забывал экспортировать один или два модуля, в результате - день на смарку (писать дубликат кода не хочется).  
Вопрос: как автоматизировать это процесс - написать макрос, который бы:
- при открытии книги переименовал текущий модуль, импортировал его последнюю версию из файла, удалил переименованный модуль;
- при закрытии книги удалил файл с модулем и экспортировал текущий?
Т.е. мне нужен макрос для управления модулями.
Спасибо.
 
Как добавить код процедуры программно, скопировать модуль
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Евгений Попович, еще и чтобы процедуры с функциями переименовывал в старом модуле)
 
В продолжение разговора.
За основу взял решение, предложенное Дмитриев Щербаковым, за что ему отдельное спасибо.

Для импорта модуля написал  функцию, которую расположил в personal.xlsb:
Код
Public Function ImportModule(ByVal ImpModuleName As String, wb As Object, ByVal FolderName As String ) As Boolean
...
Set objVBProjTo = wb.VBProject
Set objVBComp = objVBProjTo.VBComponents(ImpModuleName)

If objVBComp Is Nothing Then
... 'такого модуля нет
Else
... 'такой модуль есть и я его удаляю
 With objVBProjTo.VBComponents
   .Remove .Item(ImpModuleName )
 End With
...
endif
     
objVBProjTo.VBComponents.Import Filename:=sFullFileName
...

Но тут возникла загвоздка.
Существующие модули не всегда удаляются или удаляются не сразу. Причем по какому закону не понятно  :cry: .
В результате, например при необходимости импортировать модуль "m" и абсолютно равных прочих условиях, у меня может получиться:
1. Один модуль с именем "m" (т.е. все хорошо)
2. Два модуля с именами "m" и "m1" (т.е. старый модуль не удалился а новый переименовался)
3. Один модуль с именем "m1" (т.е. старый модуль удалился после того как импортировался новый )

Может кто подскажет, что я упускаю из виду.
Изменено: Евгений Попович - 29.03.2018 16:53:52
 
Попробуйте так:
Код
With objVBProjTo.VBComponents
   .Remove .Item(ImpModuleName )
   DoEvents
 End With
при необходимости можно сделать задержку подольше. Скорее всего ПК просто не успевает иногда внести нужные изменения, а Вы уже другую задачу подкидываете.
Может быть прокатит такой финт:
Код
Set objVBProjTo = wb.VBProject
Set objVBComp = objVBProjTo.VBComponents(ImpModuleName)

If objVBComp Is Nothing Then
'...
Else
On error resume next
Do While Not objVBComp Is Nothing
With objVBProjTo.VBComponents
   Set objVBComp = Nothing
   .Remove .Item(ImpModuleName )
   Set objVBComp = .Item(ImpModuleName)
 End With
Loop
on error goto 0
End if
Изменено: Дмитрий Щербаков - 29.03.2018 19:29:42 (добавил строку - спасибо sokol92, нашел ошибку)
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
DoEvents я пробовал. Доходило до абсурда  :D  - через строку.   Не помогает.

Предложенный цикл работает. Но тоже есть проблемы. Он   примерно в 50% случаев уходит в бесконечность.  Приходится в ручную прерывать работу макроса. Я решил дождаться  когда-же он достигнет предела. Меня хватило  минут на 5.  

Но обнаружил пару особенностей.
1. Макрос "Импорт" работает параллельно с остальными. Т.е. Excel не ждет, когда этот макрос отработает а продолжает работать параллельно. Я это обнаружил, когда после загрузки Excel полез редактировать код другого модуля и увидел, что Excel находится  в режиме выполнения макроса. Когда приостановил выполнение то оказалось, что текущее действие и есть как раз этот цикл.

2. Иногда после прерывания цикла, модуль сам удаляется. Т.е. прервал макрос "Импорт", что-то сделал в коде другого модуля, а потом увидел, что импортируемого  модуля  нет.

Такое ощущение, что задача ставится в очередь, только вот как эта очередь движется и чем ее можно протолкнуть не понятно.

Пока, вроде-бы, такое решение работает. (Взято из того-же источника)
Код
Set objTmpVBComp = objVBProjTo.VBComponents.Import(sFullName)
With objVBComp.CodeModule
    .DeleteLines 1, .CountOfLines
     sModuleCode = objTmpVBComp.CodeModule.Lines(1, objTmpVBComp.CodeModule.CountOfLines)
     .InsertLines 1, sModuleCode
End With
objVBProjTo.VBComponents.Remove objTmpVBComp
Изменено: Евгений Попович - 30.03.2018 16:41:33 (Добавил решение)
Страницы: 1
Наверх