Добрый всем день! Столкнулся с небольшой проблемой. Писал небольшой макрос, который парсит файл .frm (текстовый файл формы). Для удобства создал классы (в ВБА, наверное, 2й раз использую классы). Собственно, проблема. Есть класса CTR: [vba]
Код
Public Name As String Public Typ As String Public Attributes As Variant Public Props As Variant Public ExternData As Variant 'äëÿ ProPipe - _Points Public Height As Long Public Width As Long Public Left As Long Public Top As Long Public Cntrls As Variant Public Parent As Variant Public Index As Long Public Group As Long
[/vba] Где свойство Attributes - это массив экземпляров класса ATRBT: [vba]
Код
Public Name As String Public Value As Variant Public IsExternal As Boolean ' Внутренний атрибут - false, Внешний - true (хранится в бинарнике frx) Public Index As Long ' ссылка на строку для быстрого поиска
[/vba]
Ну а проблема возникла в такого рода коде: [vba]
Код
msgbox (oCTRL.Attributes(1).Index)
[/vba] -вызывает ошибку "Property let procedure not defined and property get procedure did not return an object" По ошибке нашёл на зарубежном сайте такое решение: [vba]
Код
msgbox (oCTRL.Attributes()(1).Index)
[/vba] Но в итоге всё-равно не понял, почему именно так. Подскажите, пожалуйста.
Добрый всем день! Столкнулся с небольшой проблемой. Писал небольшой макрос, который парсит файл .frm (текстовый файл формы). Для удобства создал классы (в ВБА, наверное, 2й раз использую классы). Собственно, проблема. Есть класса CTR: [vba]
Код
Public Name As String Public Typ As String Public Attributes As Variant Public Props As Variant Public ExternData As Variant 'äëÿ ProPipe - _Points Public Height As Long Public Width As Long Public Left As Long Public Top As Long Public Cntrls As Variant Public Parent As Variant Public Index As Long Public Group As Long
[/vba] Где свойство Attributes - это массив экземпляров класса ATRBT: [vba]
Код
Public Name As String Public Value As Variant Public IsExternal As Boolean ' Внутренний атрибут - false, Внешний - true (хранится в бинарнике frx) Public Index As Long ' ссылка на строку для быстрого поиска
[/vba]
Ну а проблема возникла в такого рода коде: [vba]
Код
msgbox (oCTRL.Attributes(1).Index)
[/vba] -вызывает ошибку "Property let procedure not defined and property get procedure did not return an object" По ошибке нашёл на зарубежном сайте такое решение: [vba]
Код
msgbox (oCTRL.Attributes()(1).Index)
[/vba] Но в итоге всё-равно не понял, почему именно так. Подскажите, пожалуйста.Roman777
Много чего не знаю!!!!
Сообщение отредактировал Roman777 - Понедельник, 03.12.2018, 16:58
Roman777, я не юзал классы... Но Вы уверены, что [vba]
Код
Public Name As String Public Attributes As Variant Public Height As Long Public Width As Long Public Left As Long Public Top As Long Public Parent As Variant Public Index As Long Public Group As Long
[/vba]это хорошая идея? Вы переопределили зарезервированные имена как паблики и теперь удивляетесь, что они как-то странно работают...
Roman777, я не юзал классы... Но Вы уверены, что [vba]
Код
Public Name As String Public Attributes As Variant Public Height As Long Public Width As Long Public Left As Long Public Top As Long Public Parent As Variant Public Index As Long Public Group As Long
[/vba]это хорошая идея? Вы переопределили зарезервированные имена как паблики и теперь удивляетесь, что они как-то странно работают...StoTisteg
Интуитивно понятный код - это когда интуитивно понятно, что это код.
Вы переопределили зарезервированные имена как паблики
. Чем это зарезервированы? Обыкновенный в ООП полиморфизм. Вот отсутствие файла примера с кодом как работают с тем самым Attributes это да, плохая идея.
Вы переопределили зарезервированные имена как паблики
. Чем это зарезервированы? Обыкновенный в ООП полиморфизм. Вот отсутствие файла примера с кодом как работают с тем самым Attributes это да, плохая идея.anvg
Вы переопределили зарезервированные имена как паблики
это же не переопределение, а определение для моего конкретного класса. (или в VBA классы по умолчанию наследники чего-то?) anvg, Сложно довольно выделить отдельно работу с Attributes. Мне проще скинуть весь файл. В нём ничего секретного. Но "небольшой", это был сарказм ...) Посчитал, что разбираться долго нужно будет... а так мб сразу в глаза что-то бросится. Я грешу на определение в классе Attributes As Variant, поэтому когда я создаю контрол:
[vba]
Код
Function CreateCTRL(s() As String, ByRef n As Long, ByRef Parent As Variant _ , ByRef ArrB() As Byte) As Variant
Dim i As Long Dim ss() As String, key(1 To 5) As String Dim k As Long Dim tmpAtrs() As ATRBT Dim tmpPrpts() As PROP Dim flgGetPnts As Boolean Dim Ctrs() As CTR
ReDim tmpAtrs(1 To 1) ReDim tmpPrpts(1 To 1) Set tmpAtrs(1) = Nothing Set tmpPrpts(1) = Nothing Ctrs = Parent.Cntrls k = GetLastLinkArr(Ctrs) Set Ctrs(k) = New CTR
ss = Split(s(n), " ") Ctrs(k).Name = ss(2) Ctrs(k).Typ = ss(1) Ctrs(k).Attributes = tmpAtrs Ctrs(k).Props = tmpPrpts Set Ctrs(k).Parent = Parent 'ccылка на родителя Ctrs(k).Index = -1 Ctrs(k).Group = -1
If InStr(1, Ctrs(k).Typ, "ProPipe") > 0 Then flgGetPnts = True End If
n = n + 1 For i = n To UBound(s) key(1) = "End" key(2) = "Begin VB.Form" key(3) = "BeginProperty " key(4) = "Begin VB.Frame " key(5) = "Begin " If (s(i) = "Begin VB.Frame LB4 ") Then sds = 1 End If If (s(i) = key(1)) Then 'тоесть, если слово целиком есть "End" CreateCTRL = Ctrs n = i Exit Function ElseIf (Left(s(i), Len(key(3))) = key(3)) Then Ctrs(k).Props = CreatePRPT(s, i, Ctrs(k).Props, ArrB) ElseIf (Left(s(i), Len(key(4))) = key(4)) Or (Left(s(i), Len(key(5))) = key(5)) Then If (IsEmpty(Ctrs(k).Cntrls)) Then Dim tmpCtrs() As CTR ReDim tmpCtrs(1 To 1) Ctrs(k).Cntrls = tmpCtrs End If Ctrs(k).Cntrls = CreateCTRL(s, i, Ctrs(k), ArrB) Else Ctrs(k).Attributes = GetValue(s(i), Ctrs(k).Attributes, i, ArrB, Ctrs(k), flgGetPnts) End If Next i End Function
Вы переопределили зарезервированные имена как паблики
это же не переопределение, а определение для моего конкретного класса. (или в VBA классы по умолчанию наследники чего-то?) anvg, Сложно довольно выделить отдельно работу с Attributes. Мне проще скинуть весь файл. В нём ничего секретного. Но "небольшой", это был сарказм ...) Посчитал, что разбираться долго нужно будет... а так мб сразу в глаза что-то бросится. Я грешу на определение в классе Attributes As Variant, поэтому когда я создаю контрол:
[vba]
Код
Function CreateCTRL(s() As String, ByRef n As Long, ByRef Parent As Variant _ , ByRef ArrB() As Byte) As Variant
Dim i As Long Dim ss() As String, key(1 To 5) As String Dim k As Long Dim tmpAtrs() As ATRBT Dim tmpPrpts() As PROP Dim flgGetPnts As Boolean Dim Ctrs() As CTR
ReDim tmpAtrs(1 To 1) ReDim tmpPrpts(1 To 1) Set tmpAtrs(1) = Nothing Set tmpPrpts(1) = Nothing Ctrs = Parent.Cntrls k = GetLastLinkArr(Ctrs) Set Ctrs(k) = New CTR
ss = Split(s(n), " ") Ctrs(k).Name = ss(2) Ctrs(k).Typ = ss(1) Ctrs(k).Attributes = tmpAtrs Ctrs(k).Props = tmpPrpts Set Ctrs(k).Parent = Parent 'ccылка на родителя Ctrs(k).Index = -1 Ctrs(k).Group = -1
If InStr(1, Ctrs(k).Typ, "ProPipe") > 0 Then flgGetPnts = True End If
n = n + 1 For i = n To UBound(s) key(1) = "End" key(2) = "Begin VB.Form" key(3) = "BeginProperty " key(4) = "Begin VB.Frame " key(5) = "Begin " If (s(i) = "Begin VB.Frame LB4 ") Then sds = 1 End If If (s(i) = key(1)) Then 'тоесть, если слово целиком есть "End" CreateCTRL = Ctrs n = i Exit Function ElseIf (Left(s(i), Len(key(3))) = key(3)) Then Ctrs(k).Props = CreatePRPT(s, i, Ctrs(k).Props, ArrB) ElseIf (Left(s(i), Len(key(4))) = key(4)) Or (Left(s(i), Len(key(5))) = key(5)) Then If (IsEmpty(Ctrs(k).Cntrls)) Then Dim tmpCtrs() As CTR ReDim tmpCtrs(1 To 1) Ctrs(k).Cntrls = tmpCtrs End If Ctrs(k).Cntrls = CreateCTRL(s, i, Ctrs(k), ArrB) Else Ctrs(k).Attributes = GetValue(s(i), Ctrs(k).Attributes, i, ArrB, Ctrs(k), flgGetPnts) End If Next i End Function
где непосредственно Атрибуты создаются функцией, постепенно расширяющей этот массив:
[vba]
Код
Function GetValue(s As String, Pr As Variant, i As Long _ , ByRef ArrB() As Byte, Optional ByRef tCtr As Variant = Nothing, _ Optional ByRef flgGetPnts As Boolean = False) As Variant Dim p() As String Dim k As Long k = GetLastLinkArr(Pr) Set Pr(k) = New ATRBT p = Split(s, "=") Pr(k).Name = p(0) Pr(k).Index = i If (flgGetPnts) Then If (InStr(1, s, "_Points") > 0) Then 'fsf = Replace(CStr(Pr(k - 1)), Chr(32), "") If (CLng(Pr(k - 1).Value) > 0) Then 'òàê è íå ïîíÿë, ïî÷åìó íåêîòîðûå Propipe ñ îòðèö _Npoint Dim pnts() As Single 'Dim ss() As String Dim offset As Long offset = Val("&h" & Right(s, Len(s) - InStr(1, s, ":")) & "&") 'offset = Val("&h" & Right(s, Len(s) - InStr(1, s, ":"))) If offset < 0 Then dsds = 1 End If 'ss = Split(s, """") pnts = GetPnts(offset, CLng(Pr(k - 1).Value), ArrB) tCtr.ExternData = pnts flgGetPnts = False End If End If
End If If (p(0) = "Height ") Then Pr(k).Value = CLng(p(1)) tCtr.Height = Pr(k).Value ElseIf (p(0) = "Width ") Then Pr(k).Value = CLng(p(1)) tCtr.Width = Pr(k).Value ElseIf (p(0) = "Left ") Then Pr(k).Value = CLng(p(1)) tCtr.Left = Pr(k).Value ElseIf (p(0) = "Top ") Then Pr(k).Value = CLng(p(1)) tCtr.Top = Pr(k).Value ElseIf (p(0) = "Index ") Then Pr(k).Value = CLng(p(1)) tCtr.Index = Pr(k).Value ElseIf (p(0) = "Group ") Then Pr(k).Value = CLng(p(1)) tCtr.Group = Pr(k).Value Else Pr(k).Value = p(1) End If GetValue = Pr End Function
[/vba]
, Attributes является Variant-ом. А его структура в VBA специфическая... всегда представляется двумерным массивом, вроде бы... (поправьте, плз). Но способа определить в классе поле-массив, я не знаю как иначе, чем Variant.
[p.s.]почему весь текст сразу не влез? Писало, что ещё 5000+ символом осталось, но при попытке всё в 1 сообщение пихнуть, говорит что лимит превышаю...[/p.s.]
где непосредственно Атрибуты создаются функцией, постепенно расширяющей этот массив:
[vba]
Код
Function GetValue(s As String, Pr As Variant, i As Long _ , ByRef ArrB() As Byte, Optional ByRef tCtr As Variant = Nothing, _ Optional ByRef flgGetPnts As Boolean = False) As Variant Dim p() As String Dim k As Long k = GetLastLinkArr(Pr) Set Pr(k) = New ATRBT p = Split(s, "=") Pr(k).Name = p(0) Pr(k).Index = i If (flgGetPnts) Then If (InStr(1, s, "_Points") > 0) Then 'fsf = Replace(CStr(Pr(k - 1)), Chr(32), "") If (CLng(Pr(k - 1).Value) > 0) Then 'òàê è íå ïîíÿë, ïî÷åìó íåêîòîðûå Propipe ñ îòðèö _Npoint Dim pnts() As Single 'Dim ss() As String Dim offset As Long offset = Val("&h" & Right(s, Len(s) - InStr(1, s, ":")) & "&") 'offset = Val("&h" & Right(s, Len(s) - InStr(1, s, ":"))) If offset < 0 Then dsds = 1 End If 'ss = Split(s, """") pnts = GetPnts(offset, CLng(Pr(k - 1).Value), ArrB) tCtr.ExternData = pnts flgGetPnts = False End If End If
End If If (p(0) = "Height ") Then Pr(k).Value = CLng(p(1)) tCtr.Height = Pr(k).Value ElseIf (p(0) = "Width ") Then Pr(k).Value = CLng(p(1)) tCtr.Width = Pr(k).Value ElseIf (p(0) = "Left ") Then Pr(k).Value = CLng(p(1)) tCtr.Left = Pr(k).Value ElseIf (p(0) = "Top ") Then Pr(k).Value = CLng(p(1)) tCtr.Top = Pr(k).Value ElseIf (p(0) = "Index ") Then Pr(k).Value = CLng(p(1)) tCtr.Index = Pr(k).Value ElseIf (p(0) = "Group ") Then Pr(k).Value = CLng(p(1)) tCtr.Group = Pr(k).Value Else Pr(k).Value = p(1) End If GetValue = Pr End Function
[/vba]
, Attributes является Variant-ом. А его структура в VBA специфическая... всегда представляется двумерным массивом, вроде бы... (поправьте, плз). Но способа определить в классе поле-массив, я не знаю как иначе, чем Variant.
[p.s.]почему весь текст сразу не влез? Писало, что ещё 5000+ символом осталось, но при попытке всё в 1 сообщение пихнуть, говорит что лимит превышаю...[/p.s.]Roman777