2017-02-16 36 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