Страницы: 1
RSS
Как разбить надстройку с классами на несколько файлов
 
Привет всем!  
Возник вопрос, ответ на который я до сих пор не могу найти.  
 
Ситуация:  
имеется надстройка (10000+ строк кода), состоящая из 50 модулей, и содержащая 20 модулей класса.    
Все модули активно работают с классами; классы объявлены с типом 1-Private (поскольку требуется создавать экземпляры классов)  
 
Всё работает, но... ориентироваться в модулях становится сложно, кроме того, потребовалось увеличение функциональности ( = добавление нескольких модулей)  
 
В связи с этим проблема: надо КАК-ТО РАЗДЕЛИТЬ НАДСТРОЙКУ на НЕСКОЛЬКО отдельных надстроек (модульная архитектура)  
 
Пытался сделать так: создаю новую настройку, перемещаю в неё пару стандартных модулей с кодом, ставлю в новой надстройке Reference на основную надстройку (которая содержит API-функции, классы и т.п., т.е. всё то, без чего код перенесённых модулей просто не будет работать)  
 
И всё бы хорошо, но из новой надстройки НЕ ВИДНЫ классы основной надстройки.  
Если же объявить классы как PublicNotCreatable, они становятся видны из новой надстройки, но, соответственно, перестают работать. (поскольку создать экземпляр класса становится невозможно)  
 
Вопрос: что можно сделать, чтобы основные функции (WinAPI, глобальные функции, классы) были в одном файле-надстройке, а модули, использующие это всё, располагались в других файлах?  
(чтобы я мог подгружать только необходимые файлы-модули; да и чтобы не таскать с проектом 4 мегабайта кода, а чтобы была возможность программно скачивать из Интернета только необходимые модули, которые я смогу обновлять при необходимости, не переделывая всю надстройку целиком)  
 
Реализовать в виде кода я смогу что угодно. Нужны лишь идеи, как это всё должно выглядеть...
 
Разве нет возможности обращаться к модулям и классам через .VBAproject.Module или .VBAproject.Сlass.
 
VovaK, код в модуле класса вызывается иначе, чем код в обычном модуле.
Bite my shiny metal ass!      
 
{quote}{login=VovaK}{date=24.10.2009 10:18}{thema=}{post}Разве нет возможности обращаться к модулям и классам через .VBAproject.Module или .VBAproject.Сlass.{/post}{/quote}  
Глобальные функции-то видны, проблема не в этом.  
 
С Private-классами так не поработать...
 
up ...
 
Не знаю поможет ли, иногда одно слово из тупика выводит.  
Копался в Additional Controls и очень удивился возможности написания пользовательских библиотек (у меня проинсталирован PROMT для Excel). Игорь покопай инет, может быть есть такая возможность...
 
> Игорь покопай инет, может быть есть такая возможность...  
 
Возможность-то есть...  
Я как-то читал про это, так в описании создания DLL в VB6 было столько "танцев с бубном", что я побоялся даже разбираться...  
 
Сейчас почитал эту тему: http://www.programmersforum.ru/showthread.php?t=70511  
и задумался...  
 
 
Создал в VB6 новый проект - ActiveX DLL  
Вроде работает.  
 
ПРОСЬБА КО ВСЕМ: Проверьте, пожалуйста, будет ли это работать на Ваших компах  
 
1) Извлеките файлы из вложения  
2) Откройте файл excel, через Tools - References установите ссылку на EducatedFool.dll (из вложения)  
3) Нажмите кнопку Запуск на листе excel  
 
должен появиться прогресс-бар...
 
Игорь, привет! Проверил. Изначально ссылка уже оказалась на месте, но прогрессбар не запустился. Принудительно ещё раз показал где эта ссылка - всё заработало.
 
Спасибо огромное всем за ответы.  
 
Вроде бы понял, почему так:  
Юрий М запустил всё без регистрации DLL  
The_Prist-у потребовалась регистрация...  
 
 
Оказывается, надо либо через Tools - References исправлять ранее введённый путь к DLL,  
либо просто зарегистрировать DLL - в этом случае Excel САМ ИСПРАВЛЯЕТ путь к библиотеке в проекте VBA.  
 
Вот уж не думал, что эти 2 способа равнозначны...  
 
 
Но, в любом случае, для меня это не составит проблемы - я делаю дистрибутив своей надстройки с помощью InnoSetup, а там легко ставится опция автоматической регистрации DLL при копировании её на комп пользователя.  
 
Теперь, вроде бы, все проблемы решились.  
Осталось только перенести кучу классов и функций в эту DLL...
 
Аналогично Юрию, ручками показал путь и работает. Изначально DLL ищет в Sistem32.
 
Игорь, зарегистрировать ActiveX DLL можно, конечно, и через Shell, но я предпочитаю так:  
 
Declare Sub DllRegisterServer Lib "EducatedFool.dll" ()  
 
Sub Auto_Open()  
 Dim p$  
 p = CurDir  
 With ThisWorkbook  
   ChDrive Left(.Path, 1)  
   ChDir .Path  
 End With  
 DllRegisterServer  
 ChDrive Left(p, 1)  
 ChDir p  
End Sub
 
> Declare Sub DllRegisterServer Lib "EducatedFool.dll" ()  
 
Спасибо, Владимир. Опять узнал много нового :)  
Но мне это вряд ли пригодится - мои DLL будут автоматически регистрироваться в момент копирования в папку System32.  
 
 
Сейчас возник другой вопрос - может, кто сталкивался с подобным...  
 
Итак, я создал в VB6  проект ActiveX DLL.  
Классы в него я успешно перенёс (не без сложностей, но, вроде, всё работает)  
 
В проект ActiveX DLL добавляются формы, стандартные модули, модули классов.  
Всё это работает внутри проекта.  
 
Но вот из VBA видны ТОЛЬКО классы, имеющиеся в DLL.  
А надо, чтобы из VBA ещё были видны и функции, расположенные в стандартном модуле проекта ActiveX DLL.  
 
Кто что может посоветовать?
 
Игорь, сначала по  первоначальному вопросу – с классом книги, связанной по reference можно работать с помощью позднего связывания (late binding).  
 
Например, имеем такую книгу надстройки с классом:  
Имя:  WB1  
Имя VBA проекта: WbWithClass  
Имя класса: Class1  
Имя стандартного модуля: Module1  
 
Функция в Module1:  
Public Function ObjClass1() As Class1  
 Set ObjClass1 = New Class1  
End Function  
 
Предположим, что в другой книге WB2 установлена ссылка на надстройку: Reference to WB1.xla  
Теперь, чтобы из WB2 работать с классом WB1 нужно в WB2 прописать код:  
Dim NewClassObj As Object  
Set NewClassObj = WbWithClass.ObjClass1  
 
А дальше работать с NewClassObj как с объектом класса, но без tooltip-ов потому что позднее связывание.  
 
По поводу функций ActiveX DLL – засунуть их в любой класс, объявить как Public, тогда они станут доступными.  
Пример:  
Dim x As New MyClassName  
Debug.Print x.MyFunc(1, 2)
Страницы: 1
Наверх