excel-vba                
            Typowe błędy
        
        
            
    Szukaj…
Kwalifikujące się referencje
 Odnosząc się do worksheet range , range lub pojedynczych cells , ważne jest pełne zakwalifikowanie odwołania. 
Na przykład:
ThisWorkbook.Worksheets("Sheet1").Range(Cells(1, 2), Cells(2, 3)).Copy
 Nie jest w pełni kwalifikowany: Odwołania do Cells nie mają powiązanego skoroszytu i arkusza roboczego. Bez wyraźnego odwołania Komórki domyślnie odnoszą się do ActiveSheet . Tak więc ten kod się nie powiedzie (wygeneruje niepoprawne wyniki), jeśli arkusz roboczy inny niż Sheet1 jest bieżącym arkuszem ActiveSheet . 
 Najprostszym sposobem na poprawienie tego jest użycie instrukcji With w następujący sposób: 
With ThisWorkbook.Worksheets("Sheet1")
    .Range(.Cells(1, 2), .Cells(2, 3)).Copy
End With
Alternatywnie możesz użyć zmiennej Arkusz. (Najprawdopodobniej będzie to preferowana metoda, jeśli kod musi odwoływać się do wielu arkuszy, np. Kopiować dane z jednego arkusza na inny).
Dim ws1 As Worksheet
Set ws1 = ThisWorkbook.Worksheets("Sheet1")
ws1.Range(ws1.Cells(1, 2), ws1.Cells(2, 3)).Copy
Innym częstym problemem jest odwoływanie się do kolekcji arkuszy roboczych bez kwalifikowania skoroszytu. Na przykład:
Worksheets("Sheet1").Copy
 Arkusz Sheet1 nie jest w pełni kwalifikowany i nie ma skoroszytu. Może to się nie powieść, jeśli w skrypcie odwołuje się wiele skoroszytów. Zamiast tego użyj jednej z następujących opcji: 
ThisWorkbook.Worksheets("Sheet1")       '<--ThisWorkbook refers to the workbook containing 
                                        'the running VBA code
Workbooks("Book1").Worksheets("Sheet1") '<--Where Book1 is the workbook containing Sheet1
Unikaj jednak używania następujących opcji:
ActiveWorkbook.Worksheets("Sheet1")     '<--Valid, but if another workbook is activated
                                        'the reference will be changed
 Podobnie w przypadku obiektów range , jeśli nie zostanie jawnie zakwalifikowany, range będzie odnosił się do aktualnie aktywnego arkusza: 
Range("a1")
Jest taki sam jak:
ActiveSheet.Range("a1")
Usuwanie wierszy lub kolumn w pętli
Jeśli chcesz usunąć wiersze (lub kolumny) w pętli, zawsze powinieneś zapętlić zaczynając od końca zakresu i cofać się na każdym kroku. W przypadku użycia kodu:
Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 1 To 4
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With
 Tęsknisz za niektórymi rzędami. Na przykład, jeśli kod usuwa wiersz 3, wówczas wiersz 4 staje się wierszem 3. Jednak zmienna i zmieni się na 4. Tak więc w tym przypadku kod pominie jeden wiersz i sprawdzi inny, który nie był wcześniej w zakresie. 
Właściwy kod to
Dim i As Long
With Workbooks("Book1").Worksheets("Sheet1")
    For i = 4 To 1 Step -1
        If IsEmpty(.Cells(i, 1)) Then .Rows(i).Delete
    Next i
End With
ActiveWorkbook vs. ThisWorkbook
 ActiveWorkbook i ThisWorkbook czasami używane zamiennie przez nowych użytkowników języka VBA bez pełnego zrozumienia, do którego obiektu się odnosi, może to powodować niepożądane zachowanie w czasie wykonywania. Oba te obiekty należą do obiektu aplikacji 
 Obiekt ActiveWorkbook odnosi się do skoroszytu, który jest obecnie w najwyższym widoku obiektu aplikacji Excel w czasie wykonywania. (np. skoroszyt, który można wyświetlić i z którym można korzystać w momencie odwołania do tego obiektu) 
Sub ActiveWorkbookExample()
'// Let's assume that 'Other Workbook.xlsx' has "Bar" written in A1.
    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Foo"
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Foo"
    Workbooks.Open("C:\Users\BloggsJ\Other Workbook.xlsx")
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"
    Workbooks.Add 1
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints nothing
End Sub
 Obiekt ThisWorkbook odnosi się do skoroszytu, do którego należy kod w momencie jego wykonywania. 
Sub ThisWorkbookExample()
'// Let's assume to begin that this code is in the same workbook that is currently active
    ActiveWorkbook.Sheet1.Range("A1").Value = "Foo"
    Workbooks.Add 1
    ActiveWorkbook.ActiveSheet.Range("A1").Value = "Bar"
    Debug.Print ActiveWorkbook.ActiveSheet.Range("A1").Value '// Prints "Bar"
    Debug.Print ThisWorkbook.Sheet1.Range("A1").Value '// Prints "Foo"
End Sub
Interfejs jednego dokumentu a wiele interfejsów dokumentów
Należy pamiętać, że program Microsoft Excel 2013 (i nowsze wersje) korzysta z interfejsu pojedynczego dokumentu (SDI), a program Excel 2010 (i poniżej) korzysta z wielu interfejsów dokumentów (MDI).
Oznacza to, że dla programu Excel 2013 (SDI) każdy skoroszyt w jednym wystąpieniu programu Excel zawiera własny wstążkowy interfejs użytkownika:
 Z kolei w przypadku programu Excel 2010 każdy skoroszyt w jednym wystąpieniu programu Excel korzystał ze wspólnego interfejsu użytkownika wstążki (MDI):  
 
Rodzi to kilka ważnych problemów, jeśli chcesz przeprowadzić migrację kodu VBA (2010 <-> 2013), które współdziałają ze Wstążką.
Należy utworzyć procedurę aktualizującą formanty interfejsu użytkownika wstążki w tym samym stanie we wszystkich skoroszytach dla programu Excel 2013 i nowszych wersji.
Uwaga:
-  Wszystkie metody, zdarzenia i właściwości okien programu Excel na poziomie aplikacji pozostają niezmienione. ( Application.ActiveWindow,Application.Windows...)
-  W programie Excel 2013 i nowszych (SDI) wszystkie metody, zdarzenia i właściwości okna na poziomie skoroszytu działają teraz w oknie najwyższego poziomu. Możliwe jest pobranie uchwytu tego okna najwyższego poziomu za pomocą Application.Hwnd
Aby uzyskać więcej informacji, zobacz źródło tego przykładu: MSDN .
Powoduje to również pewne problemy z modelowymi formularzami użytkownika. Zobacz tutaj rozwiązanie.
