Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / как сделать у своего класса открытие свойство-массив / 13 сообщений из 13, страница 1 из 1
06.11.2009, 11:09:10
    #36294088
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
Добрый день. Прошу помощи.

Есть класс, у него есть свойство - массив определенного пользователем
типа. Требуется сделать так, чтобы к этому свойству-массиву был доступ для всего проекта. Объявить свойство-массив класса сразу как Public, не дает Excel. Пробую сделать через Get/Let/Set

Код класса Library:
'свойство класса в виде массива пользовательского типа
Private inner_Book() As Record
'попытка получить значения
Public Property Get Book() As Record
(as Record выдает "Application-defined or object-defined error")
(as Object выдает "Only user defined types defined in public object modules...")
Book() = inner_Book()
End Property
---------------------------------------
Код модуля:
'пользовательский тип данных
Public Type Record
number As Long
End Type
'создание объекта
Dim myLibrary As Library
Set myLibrary = New Library

вот здесь мне нужно иметь возможность работать с элементами массива вот в таком виде
test = myLibrary.Book(1).number

как сделать чтобы это было возможно?
...
Рейтинг: 0 / 0
06.11.2009, 11:28:42
    #36294163
m
m
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
не разбраюсь в ООП, но может Вам создавать свой класс в Модуле Классов Excel... Insert-Class Module
...
Рейтинг: 0 / 0
06.11.2009, 11:32:42
    #36294174
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
ну класс там и создан)
...
Рейтинг: 0 / 0
06.11.2009, 11:36:24
    #36294188
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
testing22,

есть противоречие между декларированным желанием вернуть массив и примером обращения к как бы нему, а на самом деле к одному его элементу, причём не соответсвующим прототипу Property Get Book. Кстати, зачем создавать в памяти временный массив, и обращаться только к одному элементу?
...
Рейтинг: 0 / 0
06.11.2009, 11:46:29
    #36294224
m
m
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
Тогда не знаю :)...
...
Рейтинг: 0 / 0
06.11.2009, 12:08:42
    #36294310
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
Бенедикт,

да Вы правы, спасибо, я не разобрался в этом моменте. Правильнее сказать, что мне нужна возможность обратиться не к самому массиву, к любому элементу массива. Но при попытке сделать такой Get пишет "Private enum and user-defined types cannot be used as parameters or return types for public procedures, public data members, or fields of..."
...
Рейтинг: 0 / 0
06.11.2009, 12:09:50
    #36294319
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
обращатсья я буду в цикле ко всем элементам, это тут просто для примера я написал обращение к одному элементу
...
Рейтинг: 0 / 0
06.11.2009, 12:26:06
    #36294390
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
testing22,

а, все, вижу ошибку, теперь сделал тип Public, сейчас попробую
...
Рейтинг: 0 / 0
06.11.2009, 12:27:23
    #36294396
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
testing22,
рассмотрим такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Option Explicit

'свойство класса в виде массива пользовательского типа
Private inner_Book() As Record

Public Property Get Book(ByVal Index As Long) As Record
 Book = inner_Book(Index)
End Property

Private Sub Class_Initialize()
 ReDim inner_Book( 1  To  10 ) As Record
End Sub
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
'пользовательский тип данных
Public Type Record
   number As Long
End Type

Sub Test1()
 'создание объекта
 Dim myLibrary As Library
 Set myLibrary = New Library
 Dim test As Long
 'вот здесь мне нужно иметь возможность работать с элементами массива вот в таком виде
 test = myLibrary.Book( 1 ).number
End Sub
Казалось бы, "всё в шоколаде". Однако:
Код: plaintext
1.
2.
 myLibrary.Book( 1 ).number =  3 
 test = myLibrary.Book( 1 ).number
 Debug.Print test
Упс! Выдаётся вовсе не 3, по той же причине: property get возвращает временную копию элемента массива, которую можно изменить, но изменение это не затронет оригинал. (Впрочем, это может быть подходящим решением для некоторых ситуаций.)

Резюме: превращайте Record в класс, класс Library превращайте в коллекцию Record-ов (или создавайте класс-коллекцию Record-ов, и делайте у Library Property Get, возвращающее ссылку на экземпляр такого класса).
...
Рейтинг: 0 / 0
06.11.2009, 13:16:48
    #36294587
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
Бенедикт,

Большое спасибо за подробный ответ и совет!!!

Возник вопрос: а почему мы не можем сделать у класса свойство Let? Чтобы изменять массив.

В таком виде у меня не работает, но, возможно, я просто допустил ошибку в коде. Пишет "Definitions of property procedures for the same property are inconsistent, or property procedure has an optional parameter, a ParamArray, or an invalid Set final parameter"

Или тут сам принцип не будет работать? Можно ли передать в Property Let индекс элемента массива?

Public Property Let Book (ByVal NewValue As Long, ByVal Index As Long)
inner_Book (Index) = NewValue
End Property
...
Рейтинг: 0 / 0
06.11.2009, 13:18:17
    #36294595
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
"В таком виде не работает" - это имею в виду код, который я написал в последнем сообщении. Код из Ващего сообщения у меня работает отлично.
...
Рейтинг: 0 / 0
06.11.2009, 14:40:46
    #36294876
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
testing22,

Да, можно сделать Property Let и передать в него индекс элемента массива. Описания Property Get и Let должны соответствовать друг другу: в Property Let передаются те же параметры, что и в Property Get, плюс, последним, параметр с типом возвращаемого из Property Get результата:
Код: plaintext
1.
2.
3.
4.
5.
6.
Public Property Get Book(ByVal Index As Long) As Record
 Book = inner_Book(Index)
End Property

Public Property Let Book(ByVal Index As Long, rec As Record)
 inner_Book(Index) = rec
End Property
Таким образом, синтаксис обращения на запись будет
Код: plaintext
1.
2.
3.
 Dim r As Record
 r.number =  141 
 myLibrary.Book( 2 ) = r
 Debug.Print myLibrary.Book( 2 ).number
Сомнительное удобство, тем более, с учётом возврата свойством Get копии элемента, а не ссылки (ситуация, провоцирующая пользователя на ошибки). А ссылку можно получить, сделав из UDT класс. Или разобрав UDT на поля базовых типов.
...
Рейтинг: 0 / 0
06.11.2009, 15:33:42
    #36295078
testing22
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать у своего класса открытие свойство-массив
Бенедикт,

Большое спасибо! Теперь все ясно!
...
Рейтинг: 0 / 0
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / как сделать у своего класса открытие свойство-массив / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]