2010-11-04 5 views
6

Sto scrivendo uno script che si collegherà a me tramite il foglio di calcolo Excel e troverà se ci sono duplicati delle celle selezionate. se ci sono dei duplicati, la funzione restituirà un array di quali file sono duplicati e creerà un commento per dirmi quali sono le righe duplicate. Sono stato in grado di gestire l'errore 0 ma ora ricevo l'errore 9 quando controllo l'array se ci sono elementi in esso che utilizzano la funzione UBound. Qualcuno sa come convalidare la matrice di numeri interi se è vuota o non causa il mio codice sembra non fare il lavoro. Qui di seguito è il mio codiceErrore di matrice vuota di handle VBA

Function IsArrayEmpty(anArray As Variant) As Boolean 
    Dim i As Integer 

    On Error Resume Next 
     i = UBound(anArray, 1) 
    Select Case (Err.Number) 
     Case 0 
      IsArrayEmpty = True 
     Case 9 
      IsArrayEmpty = True 
     Case Else 
      IsArrayEmpty = False 
    End Select 
End Function 

risposta

5

Prova questo per controllare un array vuoto:

Dim arr() As String 

If (Not arr) = -1 Then 
    Debug.Print "empty" 
Else 
    Debug.Print "UBound is " & UBound(X) 
End If 

HTH!

+2

Non pretendo alcuna conoscenza speciale, ma a quanto pare questo metodo di controllo di un array vuoto sta sfruttando un bug in VBA e non dovrebbe essere utilizzato: http://stackoverflow.com/questions/183353/how-do-i- define-if-an-array-is-initialized-in-vb6/183356 # 183356 – jtolle

+0

@jtolle - il tuo link è sicuramente la discussione definitiva su questa domanda. forse questo Q dovrebbe essere un duplicato. o almeno il tuo link dovrebbe essere la risposta alla Q di Talguy. – hawbsl

+0

@jtolle Può essere. Ho usato questa cosa prima, ma siccome non l'ho creata, non rivendico alcuna virtù al riguardo. –

6

La funzione non riesce perché se non v'è alcun errore generato da UBound() (cioè la matrice si dimensiona) allora Err.Number è 0 e:

Case 0 
    IsArrayEmpty = True 

viene eseguita restituisce un risultato errato.

Il modo più semplice è quello di solo intercettare l'errore:

Function IsArrayEmpty(anArray As Variant) As Boolean 
On Error GoTo IS_EMPTY 
If (UBound(anArray) >= 0) Then Exit Function 
IS_EMPTY: 
    IsArrayEmpty = True 
End Function 
+0

che ha funzionato meglio, ma sto ancora ricevendo errore # 9 script fuori limite – Talguy

+1

'Dim a(): Debug.Print IsArrayEmpty (a)' funziona bene per me ... Make sicuro di non avere Strumenti> Opzioni> Generale> Break on all Errors set –

+0

Funziona anche per me. –

1

.. I am still getting error #9 script out of bounds

se si ottiene l'errore # 9 .... non vuol dire che si sta geting le informazioni di cui avete bisogno (array è vuoto)?

+0

che sono le informazioni che voglio ma il programma non salta al gestore degli errori, ma ottengo il pop che dice errore 9 – Talguy

+0

Ciao Talguy, hai provato Alex K. ingerenza? Secondo questo link se lo si cambia in un programma di ufficio, potrebbe essere trasferito all'altro. – CaBieberach

+0

Controllare anche questo collegamento . Sezione "Error Handling Blocks And On Error Goto". (Più istruzione "On Error" nella stessa procedura, non verrà catturata correttamente). – CaBieberach

3

La variante di array è vuota o vuota()?

'Empty' è una variante non inizializzata: IsEmpty (myVar) restituirà true ... E potresti essere ingannato nel pensare di avere una matrice vuota (che è 'Empty()', non 'Empty' - prova a tenere il passo, ci sarà un breve test dopo questa classe) perché IsEmpty (myArray) restituisce anche True.

 
Dim myVar as Variant  ' this is currently Empty, and Ubound returns an error
Dim myArray() as variant ' this is currently Empty(), and Ubound returns an error

Redim myVar(0 to 0) ' this is no longer empty, and has a valid Ubound
Redim myArray(0 to 0) ' this is no longer empty, and has a valid Ubound

un modo affidabile per controllare myVar è TypeName (myVar) - se si tratta di un array, il nome contiene parentesi:

 
If Instr(Typename(myVar), "(") > 0 then 

    ' we now know it is an array 
    If Not IsEmpty(myVar) Then 

     ' We can now check its dimensions 
     If Ubound(myVar) > 0 
      ' insert error-free code here 
     Endif 

    Endif 

Endif 

La risposta completa è 'Rilevamento di una variante di matrice in Excel VBA 'su Excellerando.

0

È possibile verificare se la matrice è vuoto recuperando elementi totali conteggio usando VBArray() oggetto di JScript (funziona con array di tipo variant, singolo o multidimensionale):

Sub Test() 

    Dim a() As Variant 
    Dim b As Variant 
    Dim c As Long 

    ' Uninitialized array of variant 
    ' MsgBox UBound(a) ' gives 'Subscript out of range' error 
    MsgBox GetElementsCount(a) ' 0 

    ' Variant containing an empty array 
    b = Array() 
    MsgBox GetElementsCount(b) ' 0 

    ' Any other types, eg Long or not Variant type arrays 
    MsgBox GetElementsCount(c) ' -1 

End Sub 

Function GetElementsCount(aSample) As Long 

    Static oHtmlfile As Object ' instantiate once 

    If oHtmlfile Is Nothing Then 
     Set oHtmlfile = CreateObject("htmlfile") 
     oHtmlfile.parentWindow.execScript ("function arrlength(arr) {try {return (new VBArray(arr)).toArray().length} catch(e) {return -1}}"), "jscript" 
    End If 
    GetElementsCount = oHtmlfile.parentWindow.arrlength(aSample) 

End Function 

Per me ci vogliono circa 0,3 mksec per ciascun elemento + 15 msec di inizializzazione, quindi la matrice di 10M elementi richiede circa 3 secondi. La stessa funzionalità potrebbe essere implementata tramite ActiveX ScriptControl (non è disponibile nelle versioni di MS Office a 64 bit, quindi è possibile utilizzare la soluzione alternativa come this).