【发布时间】:2018-09-24 15:24:46
【问题描述】:
希望在工作簿 B 中使用过滤器,其中包含工作簿 A 中的剪贴板内容。工作簿 B 名称是通配符,需要从工作簿 A 运行宏。到目前为止,我有:
Sub SwitchAndFilter()
'
Dim wb As Workbook
For Each wb In Application.Workbooks
If wb.Name Like "*ABC_*" Then wb.Activate:
With ActiveWorkbook
'code here just getting run onto workbook A, plus don't know how to pass clipboard contents to a filter
ActiveSheet.Range("$A$1:$W$501").AutoFilter Field:=3, Criteria1:="12345" ' this should be clipboard contents from Workbook A
End With
Exit Sub
Next wb
'if code gets here, it isn't already open...
End Sub
更新 1 在线获取“运行时错误 '9':下标超出范围”:
.Sheets("Sheet1").Range("AA1").Paste
根据下面的建议“应该从范围中获取过滤条件,而不是剪贴板”,我尝试首先将剪贴板粘贴到 wbB 上的范围中,然后参考该范围进行过滤。我现在拥有的完整代码是:
Sub SwitchAndFilter3()
Dim wbA As ThisWorkbook
Dim wbB As Workbook
Set wbA = ThisWorkbook
For Each wbB In Application.Workbooks
If wbB.Name Like "*ABC_*" And wbA.Name <> wbB.Name Then
'Your with should reference the context of your for, i.e. wbB, not ActiveWorkbook.
With wbB
'You should really try to avoid Activesheet
'Also, you should get the filter criteria from the range, not the clipboard.
'
.Sheets("Sheet1").Range("AA1").Paste
.ScrollColumn = 2
'
.Sheets("Sheet1").Range("$A$1:$W$501").AutoFilter Field:=3, Criteria1:=wbB.Sheets("Sheet1").Range("AA1").Value
'If you need wbB to be active:
.Activate
End With
Exit Sub
End If
Next wbB
COPY SUB FOR @ValonMiller 18 年 9 月 26 日响应以下评论中的请求
Sub CopyFirstOne()
Dim position As Integer
Dim substring As String
position = InStr(ActiveCell, " ")
If (position > 0) Then
substring = Left(ActiveCell, position - 1)
Dim MyText As DataObject
Set MyText = New DataObject
On Error Resume Next
MyText.setText substring
MyText.PutInClipboard
End If
'below macro works on it's own, but Calling from here crashes XL for a bit and gives error on PasteSpecial
'Call SwitchAndFilterWorks
End Sub
10.8.18 更新
Sub ListFiles_A3_Works()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim i As Integer
Application.Goto Reference:="Body"
Selection.ClearContents
Range("B6").Select
objFolderName = Range("A3").Value
'Create an instance of the FileSystemObject
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object
Set objFolder = objFSO.GetFolder(objFolderName)
'Set objFolder = objFSO.GetFolder(Range("A3").Value)
i = 5
'loops through each file in the directory and prints their names and path
For Each objFile In objFolder.Files
'print file name
Cells(i + 1, 1) = objFile.Name
'print file path
'Cells(i + 1, 2) = objFile.Path
i = i + 1
Next objFile
Range("B6").Select
Range("A6").Select
ActiveWindow.ScrollRow = Selection.Row
Call CopyFirstOne
End Sub
【问题讨论】:
-
工作簿是
ThisWorkbook吗? -
另外,过滤条件是否从范围(即单元格)中复制?哪个单元格在哪个工作表上?
-
为什么要激活工作表,并在
For each wb循环中使用ActiveWorkbook?只需使用If wb.Name like "whatever" Then // wb.Sheets("whateverSheet").Range([whatever])...?另外,请正确格式化代码,If语句末尾的:不正确,将不起作用。End If在哪里?你知道你在第一个Wb之后退出 sub 对吗? -
@Alex 标准应该是
Criteria1:=.Sheets("Sheet1").Range("AA1").Value。排除 wbB,因为它已经是With中的上下文。关于错误,请确保您实际上有一个工作表名称“Sheet1”,如果这实际上不是工作表的名称,那么您需要在代码中更新它。另一个潜在的问题是复制源,复制的是什么以及从哪里复制?如果它是从 Excel 外部复制的,那么如果它支持 Excel 粘贴,那么你所拥有的可能会起作用。如果您尝试从 wbA 复制某些内容,那么我看不到复制发生在这里。 -
@ValonMiller - 当我运行这个 Sub 时,已经从 wbA 进行了复制。根据您上面的注释:我已排除 wbB 并将 wbB 中的所有“Sheet1”引用重命名为实际工作表名称,但在同一行上不断收到“运行时错误'9':下标超出范围”......