首页 > 解决方案 > 简单的 VBA 宏将适用于除一台以外的所有计算机

问题描述

我编写了一个程序,它可以在我工作场所的所有计算机上运行,​​除了一台。程序错误如下:

MsgBox Workbooks(WB).Sheets(IO).Range("A1").Value

我得到一个

运行时错误 9 - 下标超出范围。

同一个文件已在多台计算机上使用,它只是一个导致错误的文件。

有没有人有这方面的经验?会不会是那台计算机上的 Excel 设置导致了这个错误?

标签: excelvba

解决方案


MsgBox Workbooks(WB).Sheets(IO).Range("A1").Value

这条指令失败的原因太多了,像这样无法判断错误来自哪里。

把它分开。

首先获取工作簿:

Dim book As Workbook
Set book = Application.Workbooks(WB)

是不是炸了?如果是这样,那么WB(可能是某个变量保存了某个工作簿的文件名?)保存了集合String中不存在的值,并且错误在其他地方。Workbooks

如果宏正在打开该工作簿,则WB应该是Workbook对象,并且没有理由从任何Workbooks集合中取消引用它:

Dim WB As Workbook
Set WB = Application.Workbooks.Open(filename)

现在您有了可以使用的Workbook对象。

如果宏没有打开该工作簿(例如,宏运行并且文件已经打开,并且与包含您的 VBA 项目的文件不是同一个工作簿 - 那将是ThisWorkbook),那么您需要确切的集合密钥检索工作簿:其他任何内容都会引发错误 9。

接下来,您将获得工作表:

Dim sheet As Worksheet
Set sheet = WB.Worksheets(IO)

或者如果WB实际上是一个String代表工作簿名称:

Dim book As Workbook
Set book = Application.Workbooks(WB)

Dim sheet As Worksheet
Set sheet = book.Worksheets(IO)

如果发生这种情况,则该Worksheets集合不包含任何以该IO变量包含的内容命名的工作表。

现在,以上所有内容都假设我们正在寻找一些工作簿中的工作

是的。该工作表在 ThisWorkbook 中。它是在宏期间打开的唯一 Excel 文档。

然后将上面的所有内容都视为多余且不适用。您只需在 VBA 项目中命名工作表模块即可。在 VBE 的Project Explorer (Ctrl+R) 中找到您想要的工作表,然后找到它的(Name)属性 (F4)。将(Name)属性(注意:这是(Name)属性,而不是Name属性)设置为有效的 VBA 标识符,例如IOSheet. 现在,您可以在项目中的任何地方使用此标识符,只要您需要访问此特定工作表。

一旦你有一个Worksheet对象,你可以得到一个Range

Dim cell As Range
Set cell = IOSheet.Range("A1")

这不会以任何方式爆炸,并且将在运行此代码的每台计算机上可靠地工作。但是MsgBox cell.Value可能 - 不是错误 9,但如果单元格A1包含工作表错误,则将Variant/Error值强制转换为 aString以将其作为函数的Prompt参数传递引发类型不匹配错误。MsgBox

因此,如果我们想在消息框中安全地显示Value单元格A1,我们需要确保它不是Variant/Error第一个 - 如果它是错误值,我们应该显示Text单元格的,因为它Value是一个变体子类型,不能强制转换为String

If Not IsError(cell.Value) Then
    MsgBox cell.Value
Else
    MsgBox cell.Text
End If

推荐阅读