2017-02-16 90 views
3

這是this問題的後續行動。通過構造,構造函數不工作的後續VBA繼承?

這裏是我的用例:我想比較兩個Excel文件逐個單元格並突出顯示不同的單元格。每個文件都有幾張紙,每張紙都有幾列,每一列都有一個標題和幾個值(如典型值)。下面是比較代碼我的選秀活動圖:

Activity Diagram

,這裏是我的選秀類圖:

Class Diagram

我的目標是使VBA的類型的東西不太繁瑣我經常做(例如比較電子表格的新版本和舊版本)。也就是說,我希望它的工作更像是Python的...我特別想寫這樣的代碼:

For Each Sheet1 In File1 
    Name1 = Sheet1.Name 
    If File2.sheet_dict.Exists(Name1) Then 
     Sheet2 = File1.Sheets(File2.sheet_dict(Name1)) 
     Sheet2.Checked = True 
     For Each Col1 In Sheet1.cols 
      hdr = Col1.Header 
      If Sheet2.header_dict.Exists(hdr) Then 
       Col2 = Sheet2.cols(Sheet2.header_dict(hdr)) 
       Col2.Checked = True 
       For Each Val1 In Col1.Vals 
        Val2 = Col2.Vals(Val1.row_number) 
        Val2.Checked = True 
        If Not Val1.Match(Val2) Then 
         Val1.formatBad() 
         Val2.formatBad() 
        End If 
       Next Val1 
       For Each Val2 In Col2.Vals 
        If Not Val2.Checked Then 
         Val2.formatBad 
        End If 
       Next Val2 
      Else 
       Col1.formatBad() 
      End If 
     Next Col1 
     For Each Col2 In File2.cols 
      If Not Col2.Checked Then 
       Col2.formatBad 
      End If 
     Next Col2 
    Else 
     Sheet1.formatBad() 
    End If 
Next Sheet1 

For Each Sheet2 In File2 
    If Not Sheet2.Checked Then 
     Sheet2.formatBad() 
    End If 
Next Sheet2 

當然我必須加載所有的數據到對象第一,但你這個想法。在VBA中嘗試這樣做是否瘋狂?

+0

嗨再次:)。在我看來,你以某種方式用你自己的方式重寫Excel的COM類模型,這是不合理的。如果你想簡化或添加一些在模型中沒有充分存在的操作,比如'Sheet_Exists(..),Header_Exists(..)'等等,我會用我自己的另外一套例程,但不能重寫類模型。 –

+0

你知道Excel的COM類模型的一個很好的圖嗎?我試圖避免使用一種通常用於遍歷範圍中的單元格的複雜方式(對於我來說,通常是在列上,然後是在列中的值)。我永遠不會記得如何獲得列中的最後一行,連續的最後一列等等。我已經爲這些函數編寫了函數,但它很不直觀。我認爲將這些代碼包裝在一個類中會簡化這個過程。我錯了嗎? –

+0

我沒有圖形或UML格式。 [This](https://msdn.microsoft.com/en-us/library/office/ff194068.aspx)是Excel對象模型的指南。我發現一個模型的*小部分*的圖形[在這裏](https://powerspreadsheets.com/excel-vba-object-model/) –

回答

1

這不是瘋了,想用VBA的面嚮對象語言 功能,但你給的使用情況並不 遠從擅長 已經提供了內置對象刪除,因此它不是」 t清楚你會從你將要增加的複雜度中獲得多少收益。有 在excel vba中有一定的權力可以利用,但它最好是在你可以的時候發揮它的優勢。

你可以很容易上色不同的細胞更有效地 通過 使用的代碼在文章的結尾 - 顯然不是做 所有你想要但很明顯的東西,不需要 訴諸OO單列和行。

Excel和vba與程序員 用於來自類似python的提供完整的 類繼承的功能完全不同。有了VBA,你只能繼續使用接口繼承,這將允許你重用代碼。但是 如果你不小心,你可以很容易地結束很多 的存根代碼,你必須從類複製到只有 能夠滿足你希望你的類實現的接口。

還有你一定要包裝你 頭從傳統的面向對象的語言圍繞未來的另一件事,這就是你在內存中的對象多少 數據複製,而不是僅僅留下 工作表和訪問他們作爲需要。有一種天生的想要將所有東西加載到對象中並從那裏操縱 --但是這是一種衝動,你應該在這種環境下真正考慮 。

如果你有一個現有的服務器後端將驗證 數據工作表和數據庫之間移動那麼至少 你有分離正常MVC關注的一種方式。實際上,您將 作爲一種網頁使用Excel作爲電子表格用戶喜歡的附加功能 。如果您沒有後端,那麼您在此 環境中確認模型和數據時必須非常小心。你應該得到 用於保護工作表的想法,除了用戶必須輸入數據的那些單元格 (假設你正在編寫代碼 以使其他人受益)。事實上,這是一個很好的想法,用不同的 顏色對輸入單元格和計算單元格進行着色,以突出顯示這種差異。後者應該受到保護 而前者在需要時可以觸發事件來驗證 輸入並更新模型狀態(並且最好在後端處理,如果 您有一個)。

保護單元還允許您隱藏工作表中明確定義的部分中的狀態信息,該部分可用於將 引回工作對象。事實上,好的使用案例是那些將定義良好的單元塊作爲用戶界面分離到特定的 類實例的例子。

在可能的情況下,您應該使用範圍參考 相同的工作表和其他部分的參考部分。命名的範圍是你的朋友在這裏。數據 驗證列表對連續數據也非常有用,並且應該儘可能使用 ,因爲它們對於他們的工作非常有效。對於 大小有限的非連續數據集,可以使用ActiveX 組合框,如果它們的 事件處理程序傳遞了後者的唯一標識符,則該組合框可以引用內存中對象實例。

當檢查事件更改時,您應該小心Worksheet_Change 輪詢,您會在網上看到很多示例。如果你不小心的話,這可以剔除一段時間。

總結:使用你可以從excel中利用的任何力量,並且避免重新發明車輪。

' Compares the sheet 1 of the workbook you're in 
' with sheet1 of the workbook file in 'Filename' 
' and colors the cells that differ between the two. 
Sub compare_workbooks_sheet1() 
    Dim Filename As String 
    Filename = "C:\MyBook.xlsm" 

    Dim wrkbk1 As Workbook 
    Set wrkbk1 = Workbooks.Open(Filename:=Filename) 

    Dim sht1 As Worksheet ' worksheet you're in 
    Dim sht2 As Worksheet ' worksheet you've opened to compare 
    Set sht1 = wrkbk1.Worksheets("Sheet1") 
    Set sht2 = ThisWorkbook.Worksheets("Sheet1") 

    Dim row As Long, col As Long 
    With sht2 
     For row = 1 To sht1.UsedRange.Rows.Count 
      For col = 1 To sht1.UsedRange.Columns.Count 
       If sht1.Cells(row, col) <> sht2.Cells(row, col) Then 
        .Cells(row, col).Interior.ColorIndex = 5 
       End If 
      Next 
     Next 
    End With 

    wrkbk1.Close 

End Sub