2017-02-16 5 views
3

これはthisへのフォローアップです。VBA継承へのフォローアップ、コンストラクタは機能していませんか?

私の使用例は次のとおりです。2つのExcelファイルをセルごとに比較して、異なるセルをハイライトしたいと思います。各ファイルにはいくつかのシートがあり、各シートにはいくつかの列があり、それぞれにヘッダーといくつかの値(典型的に)があります。ここで比較コードのための私のドラフトアクティビティ図は次のとおりです。

Activity Diagram

そして、ここでは私のドラフトクラス図である:

Class Diagram

私の目標は、物事の種類のためにVBAはあまり面倒にすることです私はしばしば(新旧のバージョンのスプレッドシートを比較するなど)します。もちろん

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 

は、私が最初にオブジェクトにロードするすべてのデータを持っていると思いますが、あなたが得る:それは私はそれがよりPythonのような仕事をしたい、です...特に、私はこのようなコードを書きたいですアイデア。 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のオブジェクト指向言語 機能を使用するためにクレイジーではありませんが、あなたが与えているユースケースは、これまで がすでに提供して優れ組み込みオブジェクトから削除されたことを ではありませんので、それはにISNあなたはそれを得るために追加される複雑さから利益を得ることを 得るでしょう。可能であれば、 のエクセルvbaを利用するのに十分な電力がありますが、それは可能であればいつでも強みを発揮するためには です。

あなたは同じように簡単に、この記事の最後にあるコードを使用することによって、細胞よりに効率的に 異なる色付け可能性 - 明らか あなたが意図しているすべてが、 は、単一のためにOOに頼る必要はありません、明らかに何かをしません列と行。

Excelとvbaは、 が完全に クラス継承を提供するpythonのようなものから来ていたのとはかなり異なっています。 VBAでは、コードの再利用を可能にする インターフェイスの継承しか持たないことに固執しています。しかし、 あなたが非常に簡単にあなたがあなたのクラスを実装するインターフェイスを満たすために できるようにクラスからクラスにコピーしなければならない多くの のスタブコードで終わることができるように慎重ではない場合。

そこもあなたは間違いなく周りの従来のオブジェクト指向言語から来たあなた 頭をラップする必要があり、別のことだ、それは同じようにそれらを ワークシートに残し、アクセスとは対照的に、あなたのメモリ内のオブジェクトに複製どのくらい データです必須。オブジェクトにすべてをロードしてそこから を操作したいと思う傾向がありますが、この環境では について実際に2度考えるべきです。

ワークシートとデータベース間を移動するデータを検証する既存のサーバーバックエンドがある場合、少なくとも には、通常のMVCに関する懸案事項を分離する方法があります。事実上、 は、スプレッドシートのユーザーが好む追加機能 を持つ一種のWebページとしてExcelを使用しています。バックエンドをお持ちでない場合は の環境でモデルとデータの検証に非常に注意する必要があります。これらのセル以外のワークシートを保護するという考え方には、 を使用する必要があります。 ユーザーはデータを入力する必要があります(自分以外の人に利益をもたらすコード を書いていると仮定します)。実際には、 アイデアの入力セルと計算されたセルを別の 色で色付けして、この違いを強調しています。後者は を保護する必要がありますが、必要な場合は の入力を検証し、モデル状態を更新するイベントをトリガーすることができます( があれば理想的にはバックエンドで作業します)。

セルを保護すると、ワークシートの 明確に定義されたセクションの状態情報を非表示にすることができ、 を参照して作業オブジェクトに戻すことができます。実際には、 が明確なセルブロックを特定の クラスインスタンスのユーザーインターフェイスとして分離しているケースがあります。

可能であれば、 同じワークシートなどのセクションを参照する範囲を使用する必要があります。名前付きの範囲はここにあなたの友人です。データ は、連続したデータにも非常に役立ちます。できるだけ効率的なので、 を使用する必要があります。サイズが制限されている 不連続データセットの場合、 イベントハンドラに固有のIDが渡された場合、メモリ内オブジェクトインスタンスを参照できるActiveX コンボボックスを使用できます。

イベントの変更をチェックするときは、Web上で多くの例が表示されるように、Worksheet_Change ポーリングに注意する必要があります。これはあなたが慎重でない場合、 はかなり時間を噛むことができます。

要約すると:あなたが得意とするパワーを使用して、 はホイールの再発明を控えてください。

' 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 
関連する問題