2016-08-04 4 views
2

В LibreOffice Basic sub Я использую кучу свойств uno в массиве. Какая самая простая Unostructure или UnoService, которую я должен «внедрить», чтобы использовать функцию getByName?Простейшая Unostructure, которая поддерживает его getByName

Пример:

dim props(1) as new com.sun.star.beans.PropertyValue 

props(0).Name = "blahblah1" 
props(0).Value = "blahblah1Value" 
props(1).Name = "blahblah2" 
props(1).Name = 3000 

Я хочу, чтобы иметь возможность использовать что-то вроде:

b = props.getByName("blahblah2").Value 

или что-то вроде (предполагается, что я "назначен" их в структуре, как-объект под названием «somestruct «):

b = somestruct.getprops.getByName("blahblah2").Value 

Как я понимаю, что это может быть сделано путем создания„UnoService“, который поддерживает getByNa меня, а затем, каким-то образом, назначая эти реквизиты этой услуге Какая «самая легкая» такая услуга? (я имею в виду услугу, которая использует меньше ресурсов)

Заранее спасибо.

ответ

2

Действительно поддерживать интерфейс XNameAccess не так просто. Услуги, реализующие этот интерфейс, предполагаются с использованием этого интерфейса для существующих именованных свойств, а не для собственных созданных.

Но вы можете воспользоваться услугой EnumerableMap, чтобы достичь того, чего вы, вероятно, захотите.

Пример:

sub testEnumerableMap 

serviceEnumerableMap = com.sun.star.container.EnumerableMap 
oEnumerableMap = serviceEnumerableMap.create("string", "any") 

oEnumerableMap.put("blahblah1", "blahblah1Value") 
oEnumerableMap.put("blahblah2", 3000) 
oEnumerableMap.put("blahblah3", 1234.67) 

msgbox oEnumerableMap.get("blahblah1") 
msgbox oEnumerableMap.get("blahblah2") 
msgbox oEnumerableMap.get("blahblah3") 
'msgbox oEnumerableMap.get("blahblah4") 'will throw error 

msgbox oEnumerableMap.containsKey("blahblah2") 
msgbox oEnumerableMap.containsValue(3000) 

if oEnumerableMap.containsKey("blahblah4") then 
    msgbox oEnumerableMap.get("blahblah4") 
end if 

end sub 

Но StarBasic с option Compatible также способен поддерживать программирование класса как VBA делает.

Пример: enter image description here

Создать модуль с именем myPropertySet.В этом поместить следующий код:

option Compatible 
option ClassModule 

private aPropertyValues() as com.sun.star.beans.PropertyValue 

public sub setProperty(oProp as com.sun.star.beans.PropertyValue) 
bUpdated = false 
for each oPropPresent in aPropertyValues 
    if oPropPresent.Name = oProp.Name then 
    oPropPresent.Value = oProp.Value 
    bUpdated = true 
    exit for 
    end if 
next 
if not bUpdated then 
    iIndex = ubound(aPropertyValues) + 1 
    redim preserve aPropertyValues(iIndex) 
    aPropertyValues(iIndex) = oProp 
end if 
end sub 

public function getPropertyValue(sName as string) as variant 
getPropertyValue = "N/A" 
for each oProp in aPropertyValues 
    if oProp.Name = sName then 
    getPropertyValue = oProp.Value 
    exit for 
    end if 
next 
end function 

Затем в стандартном модуле:

sub testClass 

oPropertySet = new myPropertySet 
dim prop as new com.sun.star.beans.PropertyValue 

prop.Name = "blahblah1" 
prop.Value = "blahblah1Value" 
oPropertySet.setProperty(prop) 

prop.Name = "blahblah2" 
prop.Value = 3000 
oPropertySet.setProperty(prop) 

prop.Name = "blahblah3" 
prop.Value = 1234.56 
oPropertySet.setProperty(prop) 

prop.Name = "blahblah2" 
prop.Value = 8888 
oPropertySet.setProperty(prop) 

msgbox oPropertySet.getPropertyValue("blahblah1") 
msgbox oPropertySet.getPropertyValue("blahblah2") 
msgbox oPropertySet.getPropertyValue("blahblah3") 
msgbox oPropertySet.getPropertyValue("blahblah4") 

end sub 
0

LibreOffice Basic поддерживает vb6 Collection type.

Dim coll As New Collection 
coll.Add("blahblah1Value", "blahblah1") 
coll.Add(3000, "blahblah2") 
MsgBox(coll("blahblah1")) 

Массивы значения свойств единственное, что будет работать для определенных интерфейсов UNO, таких как диспетчерских вызовов. Если вам просто нужен лучший способ справиться с массивами значений свойств, используйте вспомогательную функцию.

Sub DisplayMyPropertyValue 
    Dim props(0 To 1) As New com.sun.star.beans.PropertyValue 
    props(0).Name = "blahblah1" 
    props(0).Value = "blahblah1Value" 
    props(1).Name = "blahblah2" 
    props(1).Name = 3000 
    MsgBox(GetPropertyByName(props, "blahblah1")) 
End Sub 

Function GetPropertyByName(props As Array, propname As String) 
    For Each prop In props 
     If prop.Name = propname Then 
      GetPropertyByName = prop.Value 
      Exit Function 
     End If 
    Next 
    GetPropertyByName = "" 
End Function 

XNameAccess используется для контейнеров, таких как UNO Calc листов. Обычно эти контейнеры получаются из интерфейса UNO, а не создаются.

oSheet = ThisComponent.Sheets.getByName("Sheet1") 

Может объекты UNO поддерживают интерфейс XPropertySet. Обычно они также получают из интерфейса UNO, а не создаются.

paraStyleName = cellcursor.getPropertyValue("ParaStyleName") 

Возможно создание нового класса на Java, реализующего XPropertySet. Однако Basic использует вспомогательные функции вместо методов класса.

+0

(Функция GetPropertyByName так возвращаемые значения должны иметь это имя) –

+0

я использовал в прошлом и (стиль коллекции и функция, которая ищет член массива в качестве GetPropertyByName делает), но моя «идея» заключается в том, чтобы использовать что-то вроде существующей структуры, думая, что она будет более эффективной и быстрой. –

0

Я думаю, что serviceEnumerableMap ответ (до сих пор). Создание значений и их поиск были намного быстрее, чем создание реквизитов в динамическом массиве и поиск их с помощью цикла for в basic. (я не «осмеливаюсь» использовать «опцию Compatible», хотя я был большим удовольствием VB6 и VBA из-за проблем с кодом, который может возникнуть). Я использовал этот код, чтобы проверить время в форме:

SUB testlala(Event) 
    TESTPROPS(Event) 
' TESTENUM(Event) 
    MSGBOX "END OF TEST" 
END SUB 

SUB TESTENUM(Event) 
    DIM xcounter AS LONG 

    'b = now() 
    serviceEnumerableMap = com.sun.star.container.EnumerableMap 
    oEnumerableMap = serviceEnumerableMap.create("string", "any") 
    FOR xcounter= 0 TO 10000 
     oEnumerableMap.put("pr" & FORMAT(xcounter,"0000"), xcounter -10000) 
    NEXT 
    'b=now()-b 
    b = now() 
    FOR xcounter = 1 TO 5000 
     lala = Int((9000 * Rnd) +1) 
     g =oEnumerableMap.get("pr" & FORMAT(lala,"0000")) 
     'MSGBOX GetValueFromName(props,"pr" & FORMAT(xcounter,"0000")) 
    NEXT 
    b=now()-b 
    MSGBOX b*100000 
END SUB 

SUB TESTPROPS(Event) 
    DIM props() 
    DIM xcounter AS LONG 

    'b = now() 
    FOR xcounter= 0 TO 10000 
     AppendProperty(props,"pr" & FORMAT(xcounter,"0000"), xcounter -10000) 
    NEXT 
    'b=now()-b 
    b = now() 
    FOR xcounter = 1 TO 5000 
     lala = Int((9000 * Rnd) +1) 
     g = GetValueFromName(props,"pr" & FORMAT(lala,"0000")) 
     'MSGBOX GetValueFromName(props,"pr" & FORMAT(xcounter,"0000")) 
    NEXT 
    b=now()-b 
    MSGBOX b*100000 
END SUB 

REM FROM Andrew Pitonyak's OpenOffice Macro Information ------------------ 
Sub AppendToArray(oData(), ByVal x) 
    Dim iUB As Integer 'The upper bound of the array. 
    Dim iLB As Integer 'The lower bound of the array. 
    iUB = UBound(oData()) + 1 
    iLB = LBound(oData()) 
    ReDim Preserve oData(iLB To iUB) 
    oData(iUB) = x 
End Sub 

Function CreateProperty(sName$, oValue) As com.sun.star.beans.PropertyValue 
    Dim oProperty As New com.sun.star.beans.PropertyValue 
    oProperty.Name = sName 
    oProperty.Value = oValue 
    CreateProperty() = oProperty 
End Function 

Sub AppendProperty(oProperties(), sName As String, ByVal oValue) 
    AppendToArray(oProperties(), CreateProperty(sName, oValue)) 
End Sub 
Смежные вопросы