- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题:我想知道在 Excel 2003 VBA 中处理数组的最佳解决方案是什么
背景:我在 Excel 2003 中有一个超过 5000 行的宏。我在过去 2 年中构建了它,将新功能添加为新过程,这有助于分割代码和调试、更改或添加到该功能。缺点是我在多个过程中使用了许多相同的基本信息,这需要我多次将其加载到具有细微差别的数组中。我现在遇到了运行时间长度的问题,所以我现在可以完全重写。
此文件用于获取制造流程的多个项目(最多 4 个不同的设置,总共最多 10 个不同的流程,每个流程最多 1000 个步骤),其中的信息是特定于流程的,特定于分组/排序的子流程目的和数据(例如移动、库存、CT、...)
然后,它会将数据粘贴到用于管理流程的多个工作表上,使用要阅读的数据表、图表和单元格格式来表示过程流能力/历史。
流程在 Excel 文件中,而制造数据是用 7 个不同的 OO4O Oracle SQL 拉入读取的,其中一些被多次重用
数组是:
arrrFlow(1 to 1000, 1 to 4) 作为具有 4 个字符串的记录类型
arrrSubFlow(1 to 1000, 1 to 10) 作为具有 4 个字符串、2 个整数和 1 个单个的记录类型
arrrData(1 to 1000, 1 to 10) 作为记录类型,具有 1 个字符串、4 个整数、12 个长整数和 1 个单字符
arriSort(1 to 1000, 1 to 4) as Integer(用作指针数组,按组、子组和步骤顺序对流、子流和数据进行排序,同时保留原始数组按步骤顺序)
可能性:
1) 将宏重写为一个大程序,该程序将数据加载到程序中的主数组中一次
优点:在程序中标注而不是作为模块中的公共(public)变量并且未通过。
缺点:用一个大型程序而不是多个较小的程序更难调试。
2)保持宏与多个过程但传递数组
优点:使用多个较小的程序更容易调试代码。
缺点:传递数组(昂贵?)
3) 使用多个过程保留宏,但数组是模块中的公共(public)变暗变量
优点:使用多个较小的程序更容易调试代码。
缺点:公共(public)数组(昂贵?)
那么,社区的裁决是什么?有谁知道使用公共(public)数组与传递数组的费用吗?失去让我的程序专注于一个功能的便利性,这些成本中的任何一个值得吗?
更新:
我在离散级别(每步多个)加载库存数据,在聚合级别(每步一个)移动数据,并在聚合级别开始轮类库存。我逐步汇总库存数据,将其放置在工作状态类别(运行、等待等)中,并根据工作表上已有的数据创建目标。
我有一个按类型显示工作流程的流程图,目前 3 个产品具有相似但不完全相同的流程,2 个产品是不同的流程,它们相似但又不相同。我已将不同流程中的每组步骤分配为一个组和子组。
我把这些数据放在多张纸上,一些按步骤顺序,一些按组/子组顺序。我还需要按组和产品、组/子组和产品、生产线和产品的部分以及产品汇总的数据。
我使用记录类型,所以我实际上有一个可读的三维数组,arrSubFlow(1,1).strStep(第一个设备的第一个步骤的步骤名称),arrData(10,5).lngYes(昨天第 10 个步骤的移动)第 5 个设备)。
我的主要优化点将出现在我每次从头开始创建 10 个页面的部分。合并单元格、边框、标题……这是一个非常耗时的过程。我将添加一个部分,将我的数据与页面进行比较,以查看它是否需要更改,如果需要,则仅重新创建它,否则,我将清除数据的每个部分,并且只将更改的数据写入工作表。根据我的时间记录数据,这将是巨大的。然而,每当我更新代码时,我总是尝试改进代码的其他方面。我看到数据加载到结构中(数组、记录集、集合)一次 因为两者都有一点优化,但对于数据完整性更是如此,所以我没有机会为不同的工作表以不同的方式加载它。
我现在看到的远离数组的主要问题是:
* 已经对它们进行了大量投资,但这还不足以成为不改变的理由
* 不知道通过它们是否有很多成本,因为它会通过 ByRef
* 我使用排序函数创建一个排序的“指针”数组,让我可以按步骤流顺序保留数组,同时按组/子组顺序轻松引用它。
由于我一直在努力为现在和 future 编写代码,因此我不反对将数组更新为 RecordSets 或 Collections,而不仅仅是为了更改它们以学习一些很酷的东西。我的阵列可以正常工作,并且根据我的研究,它们为运行时间增加了几秒钟,对于这个 2 分钟的报告来说,数量并不多。因此,如果将来另一种结构比记录类型的二维数组更容易更新,那么请告诉我,但有没有人知道将数组传递给过程的成本,假设您没有执行 ByVal 传递?
最佳答案
您提供了很多细节,但如果不看一些代码,仍然很难准确理解发生了什么。在您的问题中,我可以确定您贯穿始终的至少 4 个大主题:制造、数据访问、VBA 和编码最佳实践。我很难确切地说出你在问什么,因为你的问题范围很大。无论哪种方式,我感谢您尝试在 VBA 中编写更好的代码。
我很难确切地理解你打算用数组做什么。你说:
The downside is that I am using much of the same base information in multiple procedures, which requires me to load it into arrays with minor differences multiple times.
ADO Recordset
之类的对象。可以提供很大帮助的对象(可能需要安装 Access...不确定)。或者您可以创建自己的。
Insert > Class Module
.在“属性”窗口(默认屏幕左下角)中,将模块的名称更改为
WorkLogItem
.将以下代码添加到类中:
Option Explicit
Private pTaskID As Long
Private pPersonName As String
Private pHoursWorked As Double
Public Property Get TaskID() As Long
TaskID = pTaskID
End Property
Public Property Let TaskID(lTaskID As Long)
pTaskID = lTaskID
End Property
Public Property Get PersonName() As String
PersonName = pPersonName
End Property
Public Property Let PersonName(lPersonName As String)
pPersonName = lPersonName
End Property
Public Property Get HoursWorked() As Double
HoursWorked = pHoursWorked
End Property
Public Property Let HoursWorked(lHoursWorked As Double)
pHoursWorked = lHoursWorked
End Property
arr(1,1)
是 ID,
arr(1,2)
是 PersonName,而
arr(1,3)
是工作时间。使用这种语法,很难知道什么是什么。假设您仍然将对象加载到数组中,而是使用
WorkLogItem
我们在上面创建的。这个名字,你就可以做
arr(1).PersonName
获取此人的姓名。这使您的代码更易于阅读。
collection
,而不是将对象存储在数组中。 .
ProcessWorkLog
.将以下代码放入其中:
Option Explicit
Private pWorkLogItems As Collection
Public Property Get WorkLogItems() As Collection
Set WorkLogItems = pWorkLogItems
End Property
Public Property Set WorkLogItems(lWorkLogItem As Collection)
Set pWorkLogItems = lWorkLogItem
End Property
Function GetHoursWorked(strPersonName As String) As Double
On Error GoTo Handle_Errors
Dim wli As WorkLogItem
Dim doubleTotal As Double
doubleTotal = 0
For Each wli In WorkLogItems
If strPersonName = wli.PersonName Then
doubleTotal = doubleTotal + wli.HoursWorked
End If
Next wli
Exit_Here:
GetHoursWorked = doubleTotal
Exit Function
Handle_Errors:
'You will probably want to catch the error that will '
'occur if WorkLogItems has not been set '
Resume Exit_Here
End Function
WorkLogItem
.最初,我们只是将其设置为计算工作总小时数。让我们测试一下我们写的代码。创建一个新模块(这次不是类模块;只是一个“常规”模块)。将以下代码粘贴到模块中:
Option Explicit
Function PopulateArray() As Collection
Dim clnWlis As Collection
Dim wli As WorkLogItem
'Put some data in the collection'
Set clnWlis = New Collection
Set wli = New WorkLogItem
wli.TaskID = 1
wli.PersonName = "Fred"
wli.HoursWorked = 4.5
clnWlis.Add wli
Set wli = New WorkLogItem
wli.TaskID = 2
wli.PersonName = "Sally"
wli.HoursWorked = 3
clnWlis.Add wli
Set wli = New WorkLogItem
wli.TaskID = 3
wli.PersonName = "Fred"
wli.HoursWorked = 2.5
clnWlis.Add wli
Set PopulateArray = clnWlis
End Function
Sub TestGetHoursWorked()
Dim pwl As ProcessWorkLog
Dim arrWli() As WorkLogItem
Set pwl = New ProcessWorkLog
Set pwl.WorkLogItems = PopulateArray()
Debug.Print pwl.GetHoursWorked("Fred")
End Sub
PopulateArray()
只需创建一个
WorkLogItem
的集合.在您的实际代码中,您可能会创建类来解析 Excel 工作表或数据对象以填充集合或数组。
TestGetHoursWorked()
代码只是演示了如何使用这些类。你注意到
ProcessWorkLog
被实例化为一个对象。实例化后,集合
WorkLogItem
成为
pwl
的一部分目的。您会在
Set pwl.WorkLogItems = PopulateArray()
行中注意到这一点.接下来,我们简单地调用我们编写的作用于集合
WorkLogItems
的函数。 .
WorkLogItem
现在包括
HoursOnBreak
的字段并且您想添加一种新方法来计算它。
WorkLogItem
添加一个属性像这样:
Private pHoursOnBreak As Double
Public Property Get HoursOnBreak() As Double
HoursOnBreak = pHoursOnBreak
End Property
Public Property Let HoursOnBreak(lHoursOnBreak As Double)
pHoursOnBreak = lHoursOnBreak
End Property
PopulateArray()
,但您可能应该为此创建一个单独的类)。然后您只需将您的新方法添加到您的
ProcessWorkLog
类(class):
Function GetHoursOnBreak(strPersonName As String) As Double
'Code to get hours on break
End Function
TestGetHoursWorked()
返回
GetHoursOnBreak
结果的方法,我们要做的就是添加以下行:
Debug.Print pwl.GetHoursOnBreak("Fred")
关于arrays - Excel VBA 编程与数组 : To Pass them or Not To Pass them?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2121093/
我正在尝试打印 timeval 类型的值。实际上我可以打印它,但我收到以下警告: 该行有多个标记 格式“%ld”需要“long int”类型,但参数 2 的类型为“struct timeval” 程序
我正在编写自己的 unix 终端,但在执行命令时遇到问题: 首先,我获取用户输入并将其存储到缓冲区中,然后我将单词分开并将它们存储到我的 argv[] 数组中。IE命令是“firefox”以启动存储在
我是 CUDA 的新手。我有一个关于一个简单程序的问题,希望有人能注意到我的错误。 __global__ void ADD(float* A, float* B, float* C) { con
我有一个关于 C 语言 CGI 编程的一般性问题。 我使用嵌入式 Web 服务器来处理 Web 界面。为此,我在服务器中存储了一个 HTML 文件。在此 HTML 文件中包含 JavaScript 和
**摘要:**在代码的世界中,是存在很多艺术般的写法,这可能也是部分程序员追求编程这项事业的内在动力。 本文分享自华为云社区《【云驻共创】用4种代码中的艺术试图唤回你对编程的兴趣》,作者: break
我有一个函数,它的任务是在父对象中创建一个变量。我想要的是让函数在调用它的级别创建变量。 createVariable testFunc() [1] "test" > testFunc2() [1]
以下代码用于将多个连续的空格替换为1个空格。虽然我设法做到了,但我对花括号的使用感到困惑。 这个实际上运行良好: #include #include int main() { int ch, la
我正在尝试将文件写入磁盘,然后自动重新编译。不幸的是,某事似乎不起作用,我收到一条我还不明白的错误消息(我是 C 初学者 :-)。如果我手动编译生成的 hello.c,一切正常吗?! #include
如何将指针值传递给结构数组; 例如,在 txt 上我有这个: John Doe;xxxx@hotmail.com;214425532; 我的代码: typedef struct Person{
我尝试编写一些代码来检索 objectID,结果是 2B-06-01-04-01-82-31-01-03-01-01 . 这个值不正确吗? // Send a SysObjectId SNMP req
您好,提前感谢您的帮助, (请注意评论部分以获得更多见解:即,以下示例中的成本列已添加到此问题中;西蒙提供了一个很好的答案,但成本列本身并未出现在他的数据响应中,尽管他提供的功能与成本列一起使用) 我
我想知道是否有人能够提出一些解决非线性优化问题的软件包的方法,而非线性优化问题可以为优化解决方案提供整数变量?问题是使具有相等约束的函数最小化,该函数受某些上下边界约束的约束。 我已经在R中使用了'n
我是 R 编程的初学者,正在尝试向具有 50 列的矩阵添加一个额外的列。这个新列将是该行中前 10 个值的平均值。 randomMatrix <- generateMatrix(1,5000,100,
我在《K&R II C 编程 ANSI C》一书中读到,“>>”和“0; nwords--) sum += *buf++; sum = (sum >>
当下拉列表的选择发生变化时,我想: 1) 通过 div 在整个网站上显示一些 GUI 阻止覆盖 2)然后处理一些代码 3) 然后隐藏叠加层。 问题是,当我在事件监听器函数中编写此逻辑时,将执行 onC
我正在使用 Clojure 和 RESTEasy 设计 JAX-RS REST 服务器. 据我了解,用 Lisp 系列语言编写的应用程序比用“传统”命令式语言编写的应用程序更多地构建为“特定于领域的语
我目前正在研究一种替代出勤监控系统作为一项举措。目前,我设计的用户表单如下所示: Time Stamp Userform 它的工作原理如下: 员工将选择他/她将使用的时间戳类型:开始时间、超时、第一次
我是一名学生,试图自学编程,从在线资源和像您这样的人那里获得帮助。我在网上找到了一个练习来创建一个小程序来执行此操作: 编写一个程序,读取数字 a 和 b(长整型)并列出 a 和 b 之间有多少个数字
我正在尝试编写一个 shell 程序,给定一个参数,打印程序的名称和参数中的每个奇数词(即,不是偶数词)。但是,我没有得到预期的结果。在跟踪我的程序时,我注意到,尽管奇数词(例如,第 5 个词,5 %
只是想知道是否有任何 Java API 可以让您控制台式机/笔记本电脑外壳上的 LED? 或者,如果不可能,是否有可能? 最佳答案 如果你说的是前面的 LED 指示电源状态和 HDD 繁忙状态,恐怕没
我是一名优秀的程序员,十分优秀!