2013-04-03 5 views
5

Piszę kod VBA, który dynamicznie ustawia właściwości niektórych wykresów, takich jak zakres danych, po otwarciu mojego pliku Excela. Dzieje się tak, ponieważ biblioteka, której używam do eksportowania programu Excel z mojego projektu .Net, nie obsługuje w pełni właściwości wykresu.Jak zrobić kod excel vba w pełni kwalifikowany/jak obejść błąd czasu pracy?

Mam 4 arkusze wykresów i 1 arkusz danych w tym pliku.

Jednak po pierwszym otwarciu pliku, następujący błąd jest pokazane:

Run-Time Error: '-2147417848 (80010108)': 

Automation 
The object invoked has disconnected from its clients. 

(także po pierwszym otwarciu, ostrzeżenie zostanie wykazane, że plik jest prawdopodobnie niepewna i ręcznie muszę zezwolić na otwarcie, ale nie jestem pewien, czy to ma jakiś związek z tym problemem)

Kolejne otwory tego pliku nie powodują błędu.

Szukałem na stackoverflow i na forach i okazało this Microsoft KB article

Na podstawie zaleceń podanych tam, starałem się zrobić mój kod pełni kwalifikowana (na przykład za pomocą Dim app As Application i Dim wb As Workbook). Jednak to nie rozwiązało mojego problemu.

Linia wykraczająca jest oznaczona symbolem **

Moje pytania są następujące:

  1. Czy ja nie dokona jakaś część mojego kodu pełne kwalifikacje?
  2. Czy są jakieś inne możliwe przyczyny tego błędu, a jeśli tak, to w jaki sposób można je rozwiązać za pomocą ?

Mój kod (w obiekcie ThisWorkbook):

Option Explicit 
Private Sub Workbook_Open() 

Dim app As Application 
Set app = Excel.Application 
Dim wb As Workbook 
Set wb = app.ThisWorkbook 

Dim lastRow As Long, lastRowString As String 
lastRow = wb.Sheets("NameOfDatasheet").UsedRange.Row - 1 + Sheets("NameOfDatasheet").UsedRange.Rows.Count 'Worksheets("NameOfDatasheet").Range("A2:G41").AutoFilter field:=1, Criteria1:="<>" 

With wb.Charts("NameOfChart1") 
.SetSourceData Source:=wb.Sheets("NameOfDatasheet").Range("A2:A" & lastRow & ",D2:E" & lastRow) 
'Styling type 1 
.SeriesCollection(1).Border.Color = RGB(255, 0, 0) 
.SeriesCollection(1).MarkerForegroundColor = RGB(255, 0, 0) 
.SeriesCollection(1).MarkerBackgroundColor = RGB(255, 0, 0) 
.SeriesCollection(1).MarkerStyle = xlMarkerStyleCircle 
.SeriesCollection(1).MarkerSize = 5 
'Styling type 2 
.SeriesCollection(2).Border.Color = RGB(0, 0, 255) 
.SeriesCollection(2).MarkerForegroundColor = RGB(0, 0, 255) 
.SeriesCollection(2).MarkerBackgroundColor = RGB(0, 0, 255) 
.SeriesCollection(2).MarkerStyle = xlMarkerStyleNone 
.SeriesCollection(2).MarkerSize = 5 
End With 

With wb.Charts("NameOfChart2") 
.SetSourceData Source:=wb.Sheets("NameOfDatasheet").Range("A2:A" & lastRow & ",H2:I" & lastRow) 
'Styling type 1 
.SeriesCollection(1).Border.Color = RGB(255, 0, 0) 
.SeriesCollection(1).MarkerForegroundColor = RGB(255, 0, 0) 
.SeriesCollection(1).MarkerBackgroundColor = RGB(255, 0, 0) 
.SeriesCollection(1).MarkerStyle = xlMarkerStyleCircle 
.SeriesCollection(1).MarkerSize = 5 
'Styling type 2 
.SeriesCollection(2).Border.Color = RGB(0, 0, 255) 
.SeriesCollection(2).MarkerForegroundColor = RGB(0, 0, 255) 
.SeriesCollection(2).MarkerBackgroundColor = RGB(0, 0, 255) 
.SeriesCollection(2).MarkerStyle = xlMarkerStyleNone 
.SeriesCollection(2).MarkerSize = 5 
End With 

Dim MaxVal As Variant, MinVal As Variant 

With wb.Charts("NameOfChart3") 
.SetSourceData Source:=wb.Sheets("NameOfDatasheet").Range("A2:A" & lastRow & ",F2:F" & lastRow) 
MaxVal = app.Max(wb.Sheets("NameOfDatasheet").Range("G2:G" & lastRow)) 
MinVal = app.Min(wb.Sheets("NameOfDatasheet").Range("G2:G" & lastRow)) 
If (MinVal = MaxVal) Then 
    MinVal = 0 
End If 
MaxVal = MaxVal + 0.1 
MinVal = MinVal - 0.1 
.Axes(xlValue).MinimumScale = MinVal 
.Axes(xlValue).MaximumScale = MaxVal 
End With 

With wb.Charts("NameOfChart4") 
**.SetSourceData Source:=wb.Sheets("NameOfDatasheet").Range("A2:A" & lastRow & ",B2:B" & lastRow)** 
MaxVal = app.Max(wb.Sheets("NameOfDatasheet").Range("C2:C" & lastRow)) 
MinVal = app.Min(wb.Sheets("NameOfDatasheet").Range("C2:C" & lastRow)) 
If (MinVal = MaxVal) Then 
    MinVal = 0 
End If 
MaxVal = MaxVal + 0.1 
MinVal = MinVal - 0.1 
.Axes(xlValue).MinimumScale = MinVal 
.Axes(xlValue).MaximumScale = MaxVal 
End With 

End Sub 
+0

+ 1 Dla ładnie wyjaśnionego pytania :) –

+0

A Shot in the dark. Dodaj 'DoEvents' przed tą linią' With wb.Charts ("NameOfChart4") ' –

+0

' Dim app Jak Application' nie jest w pełni kwalifikowany. Spowoduje to ustawienie 'app' na pierwszą bibliotekę obiektów, którą napotka w kolejności sortowania Narzędzia> Referencje. Lepiej napisać 'jak Excel.Application', aby uniknąć niejednoznaczności. – JimmyPena

Odpowiedz

1

Kilka rzeczy do rozważenia ... dlaczego nie używasz wbudowanego obiektu arkuszami, jest czystsze niż w kolekcji kart? Również, jeśli arkusz roboczy w Pytanie nie jest "pierwszy", musi mieć aktywowaną funkcję, aby móc uzyskać dostęp do pól. (W zależności od wersji programu Excel, to może trzeba aktywować w każdym razie tak polecam to robić niezależnie) można to zrobić:

wb.Sheets("nameOfWorksheet").Activate 

Albo

Worksheets("nameOfWorksheet").Activate 

Tylko uwaga tutaj wykonujesz wiele powtarzalnych połączeń w kolekcje. Nie możesz liczyć na kompilator, aby zoptymalizować to dla ciebie. Każdy collection.get(), szczególnie ten, w którym ciąg znaków jest rozdzielany na numer indeksu, je cykle. Lepiej pobrać referencję i uzyskać dostęp do arkusza roboczego za pomocą tego wskaźnika i zwolnić go po zakończeniu.

0

Miałem ten sam problem, ale starałem się znaleźć dobre rozwiązanie. 1 z głównych problemów z moim kodem i otrzymaniem tego (frustrujące) był błąd, że miałem End na końcu bloku kodu, który był częścią formularza, który zastąpiłem Me.Hide.

Kolejną rzeczą, która pomogła, było sprawdzenie, czy zmienne globalne, które zadeklarowałem (jako część modułu reprezentującego aplikację i skoroszyt), to Nothing w kodzie, który ich używa.

Innymi słowy:

If app Is Nothing Then 
    Set app = Excel.Application 
End If 

A może taka sama dla zmiennej balansu bieli. Dobrze byłoby umieścić punkty przerwania w kodzie przed użyciem skoroszytu i obiektów arkusza roboczego, aby przejść przez nie, aby zobaczyć, która linia jest urażona.

W innym przypadku sprawdź w numerze this Microsoft article, aby dowiedzieć się więcej na ten temat.

Mam nadzieję, że to pomoże.

PS. Mój kod był aktualizacją z programu Excel 2003 i działa cały czas w starej wersji bez tego błędu.