Stránka 1 z 1

Excel VBA - ListBox.RemoveItem err

Napsal: 19 bře 2015 11:33
od Adalbert
Zdravim,

mam jednoduchou proceduru, ktera mi odmazava zaznamy z ListBoxu2 pokud jsou i v ListBoxu1.
Jednoduchou, presto nefunkcni. V kodu jsem vyznacil problemovy radek.



Kód: Vybrat vše

Private Sub cmbTest_Click()

Dim i As Long

For i = 0 To Me.ListBox1.ListCount - 1
    If Me.ListBox1.List(i) <> vbNull Then
        OdstranItem Me.ListBox1.List(i)
    End If
Next i

End Sub



Kód: Vybrat vše

Private Function OdstranItem(str As String)

Dim valExists As Boolean
Dim j As Long

valExists = False

    For j= 0 To Me.ListBox2.ListCount - 1
        If Me.ListBox2.List(j) = str Then valExists = True
    Next j

    If valExists Then
        MsgBox "Zaznam " & str & " nalezen, bude vymazan", vbInformation     ' ## Msg se zobrazi spravne
        Me.ListBox2.RemoveItem str     ' ##  chyba: Neplatny argument
    Else

    End If

End Function


alternativni funkce mi take pada na stejnou chybu

Kód: Vybrat vše

Private Function OdstranItem(str As String)

Dim j As Long

    For j = 0 To Me.ListBox2.ListCount - 1
        If Me.ListBox2.List(j) = str Then
        MsgBox "Zaznam " & str & " nalezen, bude vymazan", vbInformation
        Me.ListBox2.RemoveItem str
        End If
    Next j

End Function


pokud radek odmazu zaznamu upravim na:

Kód: Vybrat vše

Me.ListBox2.RemoveItem (j)


pripadne na:

Kód: Vybrat vše

Me.ListBox2.RemoveItem j


hlasi mi to chybu tentokrat pri zpracovani funkce na radku:

Kód: Vybrat vše

 If Me.ListBox2.List(j) = str Then                    ' ## Chyba: Could not get the List property. Invalid property array index


Predem diky za rady jak z toho ven.

--- Doplnění předchozího příspěvku (19 Bře 2015 11:42) ---

Pouze pro doplneni mozna dulezitych informaci:

ListBox1 je plnen daty z Worksheetu metodou AddItem
ListBox2 je plnen daty z db Oracle opet metodou AddItem

Oba ListBoxy jsou soucasti UserForm

Re: Excel VBA - ListBox.RemoveItem err

Napsal: 19 bře 2015 13:36
od Azuzula
Z nápovědy lze vyčíst, že funkce .RemoveItem požaduje index řádku který má smazat, požaduje číselný datový typ* místo typu string. První řádek má číslo 0, druhý řádek 1 atd.

Takže Me.ListBox2.RemoveItem j by měl normálně mazat řádky listboxu.

* Pro proměnnou i a j bych radši použila datový typ Integer nebo Byte. Byte je podle mě asi vhodnější, max. 256 řádků na seznamy ve formulářích většinou postačí, příp. integer pro max. 32tis. řádků. Typ long, mimo jiné, by se hodil tak na procházení řádků listu v opravdu rozsáhlé tabulce která má víc než 32tis. záznamů. Sice to na výkonu makra nepůjde poznat, ale proč zbytečně používat datový typ dlouhý 32bitů místo 8bitů?

Re: Excel VBA - ListBox.RemoveItem err

Napsal: 19 bře 2015 14:31
od Adalbert
Diky za odpoved. Datovy tzp jiste zmenit muzu.
Priznavam, ze to, ze RemoveItem pracuje pouze s cislelnym datovym typem mi uniklo.

Kazdopadne mi nefunguje ani Me.ListBox2.RemoveItem j .

Respektive mi zafunguje pouze pri odmazani prvniho nalezeneho zaznamu, jakmile se vsak otoci loop, kod pada na radku
If Me.lsbSeznamStanic.List(j) = str Then

Chyba: Could not get the List property. Invalid property array index

Re: Excel VBA - ListBox.RemoveItem err

Napsal: 19 bře 2015 15:25
od Azuzula
To nejspíš bude tím, že po vymazání první shody se změní počet řádků v listboxu a pak už nesedí j s počtem řádků, tím pádem cyklus končí chybou a kdyby makro našlo další shodu, už nebude sedět index řádku kde se hodnota nachází s číslem v proměnné j, takže by to smazalo špatný řádek.

Po každé nalezené shodě bych nechala makro vrátit na začátek cyklu aby indexy řádků seděly. Kdyby byl v listboxu víc než jeden hledaný řetězec.

Kód: Vybrat vše

Private Function OdstranItem(str As String)
Dim j As integer
zacatek:
    For j = 0 To Me.ListBox2.ListCount - 1
        If Me.ListBox2.List(j) = str Then
            MsgBox "Zaznam " & str & " nalezen, bude vymazan", vbInformation
            Me.ListBox2.RemoveItem j
            goto zacatek
        End If
    Next j
End Function


Pokud je hledaný řetězec vždycky jen jeden, můžeš makro jednoduše ukončit příkazem exit for po nalezení a odstranění první shody.

Kód: Vybrat vše

Private Function OdstranItem(str As String)
Dim j As integer
    For j = 0 To Me.ListBox2.ListCount - 1
        If Me.ListBox2.List(j) = str Then
            MsgBox "Zaznam " & str & " nalezen, bude vymazan", vbInformation
            Me.ListBox2.RemoveItem j
            exit for
        End If
    Next j
End Function


Nebo celý cyklus můžeš otočit aby hledal od konce. Funkční jak pro jeden hledaný řetězec, tak i když jich je víc.

Kód: Vybrat vše

Private Function OdstranItem(str As String)
Dim j As integer
    For j =  Me.ListBox2.ListCount - 1 to 0 step -1
        If Me.ListBox2.List(j) = str Then
            MsgBox "Zaznam " & str & " nalezen, bude vymazan", vbInformation
            Me.ListBox2.RemoveItem j
        End If
    Next j
End Function

Re: Excel VBA - ListBox.RemoveItem err  Vyřešeno

Napsal: 19 bře 2015 15:37
od Adalbert
Vida, to zni logicky. Diky za rady.