Zakresy komórek – metody getData i getDataArray

Z Henryk Dąbrowski
Przejdź do nawigacji Przejdź do wyszukiwania
Wersja do druku nie jest już wspierana i może powodować błędy w wyświetlaniu. Zaktualizuj swoje zakładki i zamiast funkcji strony do druku użyj domyślnej funkcji drukowania w swojej przeglądarce.
02.08.2020



Szybkość operowania danymi zapisanymi w komórkach i danymi zapisanymi w tablicy

Prosty przykład pokaże nam różnicę między operowaniem na komórkach z zakresu komórek i na tablicy danych utworzonych z zakresu komórek. Zauważmy, że zmienna oRngData jest tablicą tablic, przykładowo mamy:
oRngData(0)(1) oznacza pierwszą tablicę w tablicy tablic oRngData i drugi element w tej pierwszej tablicy
oRngData(0)(2) oznacza pierwszą tablicę w tablicy tablic oRngData i trzeci element w tej pierwszej tablicy itd.
W przedstawionym niżej przykładzie operujemy na danych liczbowych – dalsze przykłady pokażą dlaczego i jakie ma to znaczenie.

Sub ZakresyGetData1()
    Dim oSht as Object, oRngA as Object, oRngB as Object, oRngC as Object
    Dim oRngData() 'tablica zawierająca dane
    Dim r as Long
    Dim t as Date, d1 as Date, d2 as Date, d3 as Date
    oSht = ThisComponent.getSheets().getByIndex(0) 'uchwyt do pierwszego arkusza
    oRngA = oSht.getCellRangeByName("A1:A100000") 'uchwyt do zakresu komórek
    oRngB = oSht.getCellRangeByName("B1:B100000") 'uchwyt do zakresu komórek
    oRngC = oSht.getCellRangeByName("C1:C100000") 'uchwyt do zakresu komórek
    
    'wypełniamy 100000 komórek kolumny A liczbami losowymi z przedziału [0,1) i mierzymy czas tej operacji
    t = Now() 'można też wykorzystać funkcję Timer()
    For r = 0 To 99999
        oRngA.getCellByPosition(0, r).Value = Rnd()
    Next r
    d1 = Now() - t 'ok. 90 sekund
    
    'wypełniamy 100000 komórek kolumny B podwojonymi wartościami z kolumny A i mierzymy czas tej operacji
    t = Now() 'można też wykorzystać funkcję Timer()
    For r = 0 To 99999
        oRngB.getCellByPosition(0, r).Value = oRngA.getCellByPosition(0, r).Value * 2
    Next r
    d2 = Now() - t 'ok. 100 sekund
        
    'wypełniamy 100000 komórek kolumny C podwojonymi wartościami z kolumny A i mierzymy czas tej operacji
    'tym razem wykorzystamy metodę getDataArray
    t = Now()
    'pobieramy dane z zakresu komórek do tablicy
    oRngData = oRngA.getDataArray() 'oRngData jest tablicą tablic
    For r = 0 To 99999
        oRngData(r)(0) = oRngData(r)(0) * 2
    Next r
    'wpisujemy dane z tablicy do zakresu komórek
    oRngC.setDataArray(oRngData)
    d3 = Now() - t 'ok. 2 sekund
    MsgBox "Czas: d1=" & d1 & "   d2=" & d2 & "   d3=" & d3
End Sub



Uwagi do metod: getDataArray i setDataArray

Korzystając z metod getDataArray i setDataArray musimy pamiętać o tym, że możemy operować jedynie na danych liczbowych i tekstowych. Niedopuszczalne są wartości logiczne i wartości typu data.

Sub ZakresyGetData2()
    Dim oSht as Object, oRng as Object
    Dim oRngData() 'tablica zawierająca dane
    oSht = ThisComponent.getSheets().getByIndex(0) 'uchwyt do pierwszego arkusza
    oRng = oSht.getCellRangeByName("A1:A5") 'uchwyt do zakresu komórek
    oRngData = oRng.getDataArray() 'pobieramy dane z zakresu komórek do tablicy tablic
        
    oRngData(0)(0) = 3.14
    oRngData(1)(0) = 128
    oRngData(2)(0) = "abcd"
    'oRngData(3)(0) = IsNumeric("abcd") 'spowoduje błąd metody setDataArray
    'oRngData(4)(0) = DateSerial(2000, 12, 31) 'spowoduje błąd metody setDataArray
        
    oRng.setDataArray(oRngData) 'wpisujemy dane z tablicy do zakresu komórek
End Sub



Uwagi do metod: getData i setData

Korzystając z metod getData i setData musimy pamiętać o tym, że możemy operować jedynie na danych liczbowych. W tym przypadku wpisanie do tablicy wartości logicznych i typu data spowoduje zapisanie odpowiadających tym wartościom liczb, a przypisany tekst zostanie pominięty i zostanie wpisana liczba zero.

Sub ZakresyGetData3()
    Dim oSht as Object, oRng as Object
    Dim oRngData() 'tablica zawierająca dane
    oSht = ThisComponent.getSheets().getByIndex(0) 'uchwyt do pierwszego arkusza
    oRng = oSht.getCellRangeByName("A1:E1") 'uchwyt do zakresu komórek
    oRngData = oRng.getData() 'pobieramy dane z zakresu komórek do tablicy tablic
    
    oRngData(0)(0) = 3.14
    oRngData(0)(1) = 128
    oRngData(0)(2) = "abcd"
    oRngData(0)(3) = IsNumeric("128")
    oRngData(0)(4) = DateSerial(2000, 12, 31)
    
    oRng.setData(oRngData) 'wpisujemy dane z tablicy do zakresu komórek
End Sub



Przykłady

Sub ZakresyGetData4()
    'pobieranie danych z zakresu komórek do tablicy i wpisywanie danych z tablicy do zakresu komórek
    Dim oSht as Object, oRng as Object
    Dim c as Long, r as Long
    Dim oRngData() 'tablica zawierająca dane
    oSht = ThisComponent.getSheets().getByIndex(0) 'uchwyt do pierwszego arkusza
    oRng = oSht.getCellRangeByName("B2:D9") 'uchwyt do zakresu komórek
    oRngData = oRng.getDataArray() 'pobieramy dane z zakresu komórek do tablicy
    
    For r = 0 To UBound( oRngData() ) 'r przebiega wiersze zakresu komórek "B2:D9"
        For c = 0 To UBound( oRngData(0) ) 'c przebiega kolumny zakresu komórek "B2:D9"
            oRngData(r)(c) = c & r
        Next c
    Next r
    
    oRng.setDataArray(oRngData) 'wpisujemy dane z tablicy do zakresu komórek
End Sub


Omówione wyżej metody możemy wykorzystać do kopiowania danych:

Sub ZakresyGetData5()
    'kopiowanie danych (tylko liczby i tekst)
    Dim oRng1 as Object, oRng2 as Object
    'uchwyt do zakresu komórek "B2:D9" w pierwszym arkuszu
    oRng1 = ThisComponent.getSheets().getByIndex(0).getCellRangeByName("B2:D9")
    'uchwyt do zakresu komórek "B2:D9" w drugim arkuszu
    oRng2 = ThisComponent.getSheets().getByIndex(1).getCellRangeByName("B2:D9")
    'kopiowanie
    oRng2.setDataArray( oRng1.getDataArray() )
End Sub



Porównanie metod getData() i getDataArray()

Należy zauważyć, że:

  • getDataArray() tworzy tablicę zmiennych typu Variant, czyli przekaże również dane tekstowe
  • getData() tworzy tablicę zmiennych typu Double, czyli przekaże tylko dane liczbowe
Sub Zakresy6()
    Dim oSht as Object, oRng as Object
    Dim A(), B(), C()
    Dim k as Long
    oSht = ThisComponent.getSheets.getByIndex(0) 'uchwyt do pierwszego arkusza
    ThisComponent.CurrentController.setActiveSheet(oSht) 'aktywacja pierwszego arkusza
    oSht.getColumns().insertByIndex(0, 1) 'dodajemy jedną kolumnę na pozycję pierwszą
    oSht.getCellRangebyName("A1").Value = 1
    oSht.getCellRangebyName("A2").Value = True '-1
    oSht.getCellRangebyName("A3").Value = DateSerial(2000, 1, 1) '36526
    oSht.getCellRangebyName("A4").String = "abcd" '0
    oRng = oSht.getCellRangeByName("A1:A4")
    A = oRng.getDataArray()
    B = oRng.getData()
    C = Array( Array( 1 ), Array( True ), Array( DateSerial(2000, 1, 1) ), Array( "abcd" ) ) 'tworzymy tablicę tablic
    MsgBox "A = [  " & A(0)(0) & " |   " & A(1)(0) & "    |     " & A(2)(0) & "      | " & A(3)(0) & " ]" & Chr(10) & _
           "B = [  " & B(0)(0) & " |   " & B(1)(0) & "    |     " & B(2)(0) & "      | " & B(3)(0) & " ]" & Chr(10) & _
           "C = [  " & C(0)(0) & " | " & C(1)(0) & " | " & C(2)(0) & " | " & C(3)(0) & " ]"
End Sub



Polecane strony internetowe

Apache OpenOffice – interface XCellRangeData





LibreOffice Calc – makra                   Strona główna