【问题标题】:VBA maintaining the program in memoryVBA 在内存中维护程序
【发布时间】:2011-06-27 23:38:38
【问题描述】:

抱歉,我不知道这是否简单,甚至不知道问题是否适合更大的编程方案。

所以以我简单的方式,我的程序一直是这样的:1. 启动程序,2. 等待程序运行,3. 程序完成并消失。

我现在正在做的是从一长串交易(10,000 个)中创建一个表。该表有几个组合框供用户选择过滤器。现在,每次用户更改过滤器时,都会重新处理整个日志,这需要半分钟或一分钟。

我宁愿将交易日志保存在内存中,或者以某种方式隐藏但更直接可用。但不要让程序在后台“旋转”。因此,用户可以在不知道程序已在后台准备就绪的情况下继续使用 Excel,以防他们以后想要更新表格,或者不。

这有意义吗?如果它不能在 VBA 中完成,我仍然很好奇它将如何在另一个环境中完成,比如 C#,如果可以的话。谢谢。

【问题讨论】:

  • 我想我可以使用一个无模式的用户表单,标题为“请忽略这个框”(我最喜欢的标志“远离这个标志”!)。但是,对于组合框 _Change 的用户表单显示将如何与我的(多种)事件进行交互,是否有人有一个快速的答案?
  • 我想我可以将组合框移动到用户窗体...。这需要更多的工作,但如果需要...

标签: vba excel


【解决方案1】:

如果期权交易的更新频率足够低,您可以将期权交易的读取和处理与过滤过程分开: 第 1 步 - 刷新 - 读取日志并处理它们,将结果存储在全局容器中(数组、集合、字典、对象......) 第 2 步 - 用户请求 - 显示表单 - 用户选择过滤器 - 显示/存储从全局容器中提取的结果。

【讨论】:

  • 我想弄清楚的是,一旦创建了输出的第一个版本,如何在后台保持全局容器处于活动状态——而不占用系统或对除此程序外,否则使用 E​​xcel。
  • 全局容器将在 excel 会话期间保持活动状态,或者直到您杀死它们。除非它们消耗大量内存,否则它们不会对 Excel 产生任何影响。
  • 抱歉,Charles,我觉得我遗漏了一些明显的东西。你的意思是在最后的 End Sub 语句之后有一个声明吗?假设我将数据读入一些大型数组。然后我从这些数组创建一个输出表。然后按照我在最后一个 End Sub 的惯常做法,数组消失了。您是说我可以以它们仍然存在的方式声明数组吗?或者是否有一个命令我可以用来让程序保持静态,处于一种静止状态,潜在但准备好对这些数组进行操作,比如保持模式(但不消耗处理器周期)?
  • 只需在第一个 Sub 之前的模块标题中将您的数组/容器声明为 Public,它们将作为全局对象持续存在,直到 Excel 会话结束或您专门销毁它们。
  • 抱歉,我当时忘记将此标记为已接受。我不知道 globals 有这个方便的特性。我很兴奋,我跑去实现这个想法。谢谢。
【解决方案2】:

有多种选择

  1. 首先,代码结构是否正确?例如,您真的需要重新处理所有内容还是重新编写更有效?
  2. 如果您无法避免资源密集型代码,请使用进度条或消息通知用户。还可以考虑使用 DoEvents,它可以释放操作系统,以便 Excel 可以处理其他事件。
  3. DoEvents 又慢又脏。更好看这个链接DoEvents is slow!!! Here are faster methods
  4. 重写代码以异步工作。创建一个类、一个处理程序并异步处理每个事务。
  5. 您可以编写一些 VBScript/Javascript 并将任务推出以独立于 Excel/VBA 运行。例如有一个例子Here
  6. 不要使用 VBA :)

编辑:你是如何过滤的?如果您要遍历数组测试标准中的数千个项目,它可能会非常慢。 Excel 的Advanced Filter 非常快,可以快速处理具有多个条件的数十万行。

【讨论】:

  • 谢谢,osknows。我的第一反应是对您的建议 1 和 6。首先是一点背景:交易是期权交易。阅读它们需要相当多的处理,因为它们来自不同的来源,具有不同的符号约定和单位。并且因为必须计算某些特征。我将每笔交易读入一个期权交易对象。然后我将这些交易编译成几个不同(重叠)的投资组合——交易台、交易簿(在台下)、底层证券类型等。用户从所有组合中选择一个特定的投资组合。投资组合远小于...
  • 其基础的交易集,在内存消耗中。哦,期权组合是另一个对象。我想到的第一件事是,也许我可以将投资组合数据输出到一张表中,然后只读取它而不是重新读取所有交易。这样做的困难是创建大量代码以文本形式导出和导入。 (这会在 C# 中“序列化”一个对象吗?这大概是 VBA 不能做到的?)除了导出和导入文本(可能还有序列化),我不知道建议 4 对这个问题还有什么意义——?
  • 哦,就过滤和读取而言——我一次遍历交易日志的行,读取文本,然后在代码中进行各种处理。现在的“过滤”主要是通过从包含所有投资组合对象的字典中选择一个键来完成的(其中键与用户在组合框中选择的字段匹配)。我的意思是在将交易对象添加到投资组合对象的级别上开发更多过滤。这将需要,当 For/Each 循环通过 Deal 对象的 Dictionary 时,将条件应用于交易属性......
  • 在添加到 Portfolio 对象之前。 PS,在第一条评论中,我的意思是“对建议 1 和 4 的反应”(不是 6)。关于#6——如果由我决定的话……
  • @RomnieEE2 - 很难评论,因为我们不知道所涉及的处理。但是,超过 1 分钟的等待时间似乎很长。如果事情真的需要这么长时间来计算,我会考虑对所有/最请求的数据运行夜间批处理作业,存储在数据库中并通过界面即时查找。
【解决方案3】:

当 Excel VBA 中的宏运行时,用户无法再使用 Excel,运行 VBA 会“卡住”整个程序。

这里有一些提示可以帮助您找到解决问题的方法:

  • 保持 vba 运行:在启动组合框时首次加载数据,然后在用户每次请求时向用户显示结果,但保持组合框加载,以便 vba 保持其上下文和内存
  • 在 Excel 工作表中加载数据,甚至隐藏,然后在用户要求某些数据时使用它
  • 向我们提供更多信息,了解您正在做什么、从何处加载数据、如何缓存数据、您当前的代码是什么、您尝试了什么……以便我们为您提供更多帮助

问候,

最大

【讨论】:

  • 保持 VBA 运行是我的想象。保持加载的建议是我认为我可以尝试的想法。是否会对 Excel 的使用产生明显的影响,代码“运行”只是通过加载某些内容而没有处理其他内容?
  • AFAIK,让代码“运行”在于保持用户看到的用户表单在屏幕上。这就是为什么我建议将数据存储在工作簿本身以从宏中“释放”用户
  • 我明白了,谢谢。按照目前的设计,用户选择的组合框位于工作表上。所以我想象的是用户能够正常使用工作表,然后随意使用仍在内存中的数据更新表格。
  • 抱歉,它没有按您预期的方式工作。我希望你能找到一种方法让它正常工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
相关资源
最近更新 更多