excel – 如何在处理表时编写清晰且可维护的代码?

在我的项目中,我经常利用表和底层的ListObjects和ListColumns.我喜欢它们,因为它们比裸露的Range对象更容易引用和更新.然而,我仍然没有找到一种理智且可维护的方法来处理由多个ListColumns组成的多个ListObject,并在项目的所有工作表中引用.

假设我将Workheet((Name)属性设置为“WorksheetA”)包含具有少量列的表(称为TableA)(称为Column1,Column2,…,Column10).

现在我想引用另一个工作表的代码中的一个列.我可以这样做:

WorksheetA.ListObjects("TableA").ListColumns("Column7")

现在,直接使用字符串是一种不好的做法,因为它很难维护并且容易出错.

所以现在怎么办?

我可以创建专用模块来存储我的字符串作为常量.例如,名为“Constants”的模块:

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用作列名作为示例.我们假设列具有更有意义的名称.

最佳答案 这是我的两分钱.我不是一个受过良好教育的程序员,但我确实得到报酬,所以我想这让我很专业.

第一道防线是我创建了一个类来建模表.我从表中填写类,没有其他代码甚至知道数据的位置.当我初始化时,我将运行代码

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模块中设置.

如果MGlobals占用超过半个屏幕,我做错了什么,我需要退后一步思考我想要完成的事情.然后我做了一个自定义课程.

点赞