在我的项目中,我经常利用表和底层的ListObjects和ListColumns。我喜欢它们,因为它们比裸露的Range对象更容易引用和更新。然而,我仍然没有找到一种理智且可维护的方法来处理由多个ListColumns组成的多个ListObject,并在项目的所有工作表中引用。
让我们说我的工作表((名称)属性设置为" WorksheetA")包含几个列的表(称为TableA)(称为Column1,Column2,...,Column10) )。
现在我想引用另一个工作表代码中的一个列。我可以这样做:
WorksheetA.ListObjects("TableA").ListColumns("Column7")
现在,直接使用字符串是一种不好的做法,因为它很难维护并且容易出错。
那么现在呢?
我可以创建专用模块来存储我的字符串作为常量。例如,模块名为"常量":
Public Const TABLE_A As String = "TableA"
Public Const COLUMN7 As String = "Column7"
然后我的引用可以转换为:
WorksheetA.ListObjects(Constants.TABLE_A).ListColumns(Constants.COLUMN7)
但是,这种解决方案有一些缺点:
我可以在WorksheetA中存储常量,并通过公共函数使它们可用,如:
Private Const TABLE_A As String = "TableA"
Private Const COLUMN7 As String = "Column7"
Public Function GetTableAName() As String
GetTableAName = TABLE_A
End Function
Public Function GetTableA() As ListObject
Set GetTableA = WorksheetA.ListObjects(TABLE_A)
End Function
Public Function GetTableAColumn7() As ListColumn
Set GetTableAColumn7 = GetTableA().ListColumns(COLUMN7)
End Function
这个解决方案实际上解决了上面提到的所有三个问题,但它仍然有点"脏"并且耗时,因为添加新表引入了为每列创建函数的要求。
你更了解如何处理这个问题吗?
EDIT1(为清晰起见):我们假设用户不得更改任何名称(表名和列名)。如果用户这样做,那就是他/她的责任。
EDIT2(为清晰起见):我仅将Column7用作列名作为示例。让我们假设列有更有意义的名称。
答案 0 :(得分:1)
这是我的两分钱。我不是一个受过良好教育的程序员,但我确实得到报酬,所以我想这让我很专业。
第一道防线是我创建了一个用于建模表的类。我从表中填写类,没有其他代码甚至知道数据的位置。初始化时,我会运行像
这样的代码clsEmployees.FillFromListObject wshEmployees.ListObjects(1)
然后在课堂上,代码看起来像
vaData = lo.DataBodyRange.Value
...
clsEmployee.EeName = vaData(i,1)
clsEmployee.Ssn = vaData(i,2)
etc
每个工作表只有一个ListObject。这是我的规则,我永远不会破坏它。有权访问工作表的任何人都可以重新排列列并破坏我的代码。如果我想使用Excel作为数据库,有时我会这样做,那么这就是我冒的风险。如果它非常重要以至于我无法承担这种风险,那么我将数据存储在SQL Server,SQLite或JET中。
我可以实际调用ListColumns名称,而不是将范围放在数组中。这样,如果有人重新安排了列,我的代码仍然有效。但它引入了他们可以重命名列,所以我只是将一个风险换成另一个。它会使代码更具可读性,因此它可能是您想要进行的交易。我喜欢从阵列中填充的速度,这就是我所做的交易。
如果我的项目足够小或者应该直接使用ListObjects,那么我遵循与任何字符串相同的规则。
如果MGlobals占用超过半个屏幕,我做错了什么,我需要退后一步思考我想要完成的事情。然后我做了一个自定义课程。