我无法弄清楚为什么这会给我一个运行时错误9(是的,文件存在并加载)

时间:2016-11-23 20:57:06

标签: excel vba excel-vba

Sub CopyColumnWidths(FileName1, SheetName1, FileName2, SheetName2)
    ColumnNumber = 1
    Check = WorksheetFunction.CountA(Workbooks(FileName1).Sheets(SheetName1).Columns(ColumnNumber))
    Do While Check > 0
        ColumnLetter = LastColumnLetter(ColumnNumber)
        Workbooks(FileName2).Sheets(SheetName2).Columns(ColumnNumber).ColumnWidth = Workbooks(FileName1).Sheets(SheetName1).Columns(ColumnNumber).ColumnWidth
        ColumnNumber = ColumnNumber + 1
        Check = WorksheetFunction.CountA(Workbooks(FileName1).Sheets(SheetName1).Range(ColumnLetter & ":" & ColumnLetter))
    Loop
End Sub

好的,这是我的代码。我已经验证所有文件名和工作表名称都存在并在Excel的同一实例中进行了说明。我检查了拼写错误,多余字符和“隐形”字符,但没有一个字符存在。

我试过,为了排除故障,放入一个工作簿(FileName1).Activate,它也不起作用。在不同的代码中,特定文件确实被隐藏,但是在执行此代码时,该工作簿是可见的并且存在。

对于我的生活,我无法弄清楚为什么这会破坏并且可以用一只手。

如果重要的话,这将在Excel 2013上运行,64位。

-------更多信息

FileName1是“Original Datasheet.xlsx” FileName2是“Split Datasheet.xlsx” SheetName1(和SheetName2)是“1a。Contents”

当我尝试激活FileName2时,它可以正常工作。当我尝试激活FileName1时,它失败了。工作表名称无关紧要,它不会“看到”FileName1,即使它存在,我可以在“切换Windows”下拉列表中选择它。

对于第一次没有阅读标题的人再次重复:是的,所有文件都加载到同一个Excel实例中。所有文件都存在。

2 个答案:

答案 0 :(得分:1)

我一直在看这个。

FileName1被称为“Orignial Datasheet.xlsx”而非“Original Datasheet.xlsx”

这就是它没有连接的原因。我的错,抱歉打扰了所有人。

答案 1 :(得分:1)

我没有得到你的答案,但运行时错误9听起来很像这些价值观中的一个并不是你认为的那样 - 并且你使用它的代码很难说清楚确切地说它在哪里爆炸。

首先转过来:

Sub CopyColumnWidths(FileName1, SheetName1, FileName2, SheetName2)

进入此(假设从同一模块中调用该过程 - 如果从另一个模块调用该过程,则将其设为Public Sub):

Private Sub CopyColumnWidths(ByVal FileName1 As String, ByVal SheetName1 As String, ByVal FileName2 As String, ByVal SheetName2 As String)

更改您的签名以使用按值传递的String参数不应该以任何方式破坏您的代码,但会使事情更加明确,从而提高可读性并使您的意图更清晰

继续前进。

ColumnNumber = 1

来自哪里?宣布它。将Option Explicit粘贴到模块的顶部,然后声明每个变量,直到您的代码再次编译(Option Explicit将使VBA拒绝编译使用未声明变量的代码)。

Dim ColumnNumber As Long
ColumnNumber = 1

现在我们知道ColumnNumberCheck是在同一范围内声明的局部变量(对吗?),我们继续:

Dim Check As Long
Check = WorksheetFunction.CountA(Workbooks(FileName1).Sheets(SheetName1).Columns(ColumnNumber))

这一行做了太多事情:我们不知道Workbooks(FileName1)正在取得成功,我们也不知道其Sheets(SheetName1)正在取得成功 - 但我们称之为Columns成员,无论是蓝天还是阳光。

不要假设蓝天和阳光。

分解。

Dim sourceBook As Workbook
Set sourceBook = Workbooks(FileName1)

Dim sourceSheet As Worksheet
Set sourceSheet = sourceBook.Worksheets(SheetName1)

Check = WorksheetFunction.CountA(sourceSheet.Columns(ColumnNumber))

如果您的代码运行到那时为止,您的问题已经解决了一半 - 您在此处遇到同样的问题,并且您正在获取相同的WorkbookWorksheet个对象再次 - 相反,将其分解,分配本地对象变量,重用它们

Workbooks(FileName2).Sheets(SheetName2).Columns(ColumnNumber).ColumnWidth = Workbooks(FileName1).Sheets(SheetName1).Columns(ColumnNumber).ColumnWidth
Dim destinationBook As Workbook
Set destinationBook = Workbooks(FileName2)

Dim destinationSheet As Worksheet
Set destinationSheet = destinationBook(SheetName2)

destinationSheet.Columns(ColumnNumber).ColumnWidth = sourceSheet.Columns(ColumnNumber).ColumnWidth

ColumnNumber = ColumnNumber + 1
Check = WorksheetFunction.CountA(sourceSheet.Range(ColumnLetter & ":" & ColumnLetter))

逐行( F8 )这个代码逐行,然后你就会确切地知道哪个指令正在爆炸。将所有内容塞进尽可能少的代码行中,并链接2,3,4个成员访问假设它将"只是工作" 使得几乎不可能知道它。

  

以前隐藏FIleName1窗口但后来取消隐藏它的代码是否可能搞砸了?我必须这样做,因为 Excel不断将数据放在错误的工作簿上,除非我隐藏它

这听起来像你有代码(其他地方吗?)明确或(更可能是?)隐式地使用ActiveSheetActiveWorkbook

如果您发现自己使用了不合格的RangeCellsRowsColumnsNames来电,则您会隐含地提及有效片。使用您要引用的工作表对象,使用显式限定的成员调用替换它们。没有魔力,Excel(实际上是VBA)无法猜出你的意图;它并没有“继续将数据放在错误的工作簿上”#34; - 它将数据准确地放在您告诉它的位置。隐藏工作簿只是一个非常糟糕的解决方法:你仍然没有明确地明确你想要把它放在哪里。