2015-06-03 106 views
0

我已经编写了输出三列信息以及打印文件名的程序的代码。我通常在该文件夹中运行20个文件的程序,所以我不会用太多的信息压垮事情,因为有超过2000个文件。VBA - 可以创建一个链接到代码的按钮?

是否可以创建一个按钮,它将输出相同的信息,但仅用于单个文件名输入?我希望能够在搜索中键入文件名,并搜索超过2000个文件的文件夹,以便为那个特定文件输出这三列信息。

东西是这样的: enter image description here

Option Explicit 

Sub LoopThroughDirectory() 

    Const ROW_HEADER As Long = 10 

    Dim objFSO As Object 
    Dim objFolder As Object 
    Dim objFile As Object 
    Dim MyFolder As String 
    Dim StartSht As Worksheet, ws As Worksheet 
    Dim WB As Workbook 
    Dim i As Integer 
    Dim LastRow As Integer, erow As Integer 
    Dim Height As Integer 
    Dim RowLast As Long 
    Dim f As String 
    Dim dict As Object 
    Dim hc As Range, hc1 As Range, hc2 As Range, hc3 As Range, d As Range 

    Set StartSht = Workbooks("masterfile.xlsm").Sheets("Sheet1") 

    'turn screen updating off - makes program faster 
    Application.ScreenUpdating = False 
    'Application.UpdateLinks = False 

    'location of the folder in which the desired TDS files are 
    MyFolder = "C:\Users\trembos\Documents\TDS\progress\" 

    'find the headers on the sheet 
    Set hc1 = HeaderCell(StartSht.Range("B1"), "HOLDER") 
    Set hc2 = HeaderCell(StartSht.Range("C1"), "CUTTING TOOL") 

    'create an instance of the FileSystemObject 
    Set objFSO = CreateObject("Scripting.FileSystemObject") 
    'get the folder object 
    Set objFolder = objFSO.GetFolder(MyFolder) 
    i = 2 




    'loop through directory file and print names 
'(1) 
    For Each objFile In objFolder.Files 
     If LCase(Right(objFile.Name, 3)) = "xls" Or LCase(Left(Right(objFile.Name, 4), 3)) = "xls" Then 
'(2) 
      'print file name to Column 1 

      'Open folder and file name, do not update links 
      Set WB = Workbooks.Open(fileName:=MyFolder & objFile.Name, UpdateLinks:=0) 
      Set ws = WB.ActiveSheet 


'(3) 
       'find CUTTING TOOL on the source sheet 
       Set hc = HeaderCell(ws.Cells(ROW_HEADER, 1), "CUTTING TOOL") 
       If Not hc Is Nothing Then 

        Set dict = GetUniques(hc.Offset(1, 0)) 
        If dict.count > 0 Then 
         Set d = StartSht.Cells(Rows.count, hc2.Column).End(xlUp).Offset(1, 0) 
         'add the values to the masterfile, column 3 
         d.Resize(dict.count, 1).Value = Application.Transpose(dict.keys) 
        End If 
       Else 
        'header not found on source worksheet 
       End If 

'(4) 
       'find HOLDER on the source sheet 
       Set hc3 = HeaderCell(ws.Cells(ROW_HEADER, 1), "HOLDER") 
       If Not hc3 Is Nothing Then 

        Set dict = GetUniques(hc3.Offset(1, 0)) 
        If dict.count > 0 Then 
         Set d = StartSht.Cells(Rows.count, hc1.Column).End(xlUp).Offset(1, 0) 
         'add the values to the master list, column 2 
         d.Resize(dict.count, 1).Value = Application.Transpose(dict.keys) 
        End If 
       Else 
        'header not found on source worksheet 
       End If 

'(5) 
      With WB 
       'print TDS information 
       For Each ws In .Worksheets 
         'print the file name to Column 1 
         StartSht.Cells(i, 1) = objFile.Name 
         'print TDS name from J1 cell to Column 4 
         With ws 
          .Range("J1").Copy StartSht.Cells(i, 4) 
         End With 
         i = GetLastRowInSheet(StartSht) + 1 
       'move to next file 
       Next ws 
'(6) 
       'close, do not save any changes to the opened files 
       .Close SaveChanges:=False 
      End With 
     End If 
    'move to next file 
    Next objFile 
    'turn screen updating back on 
    Application.ScreenUpdating = True 
    ActiveWindow.ScrollRow = 1 
'(7) 
End Sub 

'(8) 
'get all unique column values starting at cell c 
Function GetUniques(ch As Range) As Object 
    Dim dict As Object, rng As Range, c As Range, v 
    Set dict = CreateObject("scripting.dictionary") 
    For Each c In ch.Parent.Range(ch, ch.Parent.Cells(Rows.count, ch.Column).End(xlUp)).Cells 
     v = Trim(c.Value) 
     If Len(v) > 0 And Not dict.exists(v) Then 
      dict.Add v, "" 
     End If 
    Next c 
    Set GetUniques = dict 
End Function 

'(9) 
'find a header on a row: returns Nothing if not found 
Function HeaderCell(rng As Range, sHeader As String) As Range 
    Dim rv As Range, c As Range 
    For Each c In rng.Parent.Range(rng, rng.Parent.Cells(rng.Row, Columns.count).End(xlToLeft)).Cells 
     If Trim(c.Value) = sHeader Then 
      Set rv = c 
      Exit For 
     End If 
    Next c 
    Set HeaderCell = rv 
End Function 

'(10) 
Function GetLastRowInColumn(theWorksheet As Worksheet, col As String) 
    With theWorksheet 
     GetLastRowInColumn = .Range(col & .Rows.count).End(xlUp).Row 
    End With 
End Function 

'(11) 
Function GetLastRowInSheet(theWorksheet As Worksheet) 
Dim ret 
    With theWorksheet 
     If Application.WorksheetFunction.CountA(.Cells) <> 0 Then 
      ret = .Cells.Find(What:="*", _ 
          After:=.Range("A1"), _ 
          Lookat:=xlPart, _ 
          LookIn:=xlFormulas, _ 
          SearchOrder:=xlByRows, _ 
          SearchDirection:=xlPrevious, _ 
          MatchCase:=False).Row 
     Else 
      ret = 1 
     End If 
    End With 
    GetLastRowInSheet = ret 
End Function 
+0

如果我理解正确,您希望在工作表中有一个按钮将运行VBA /宏的Excel文件? – IMTheNachoMan

+0

是的,我相信如此。我对VBA不是非常熟悉,这就是为什么这个犹豫不决。但是,是的,这听起来很准确 – Taylor

+0

嗨泰勒。对的,这是可能的。 http://www.techonthenet.com/excel/formulas/dir.php https://msdn.microsoft.com/en-us/library/office/ff194819.aspx http://stackoverflow.com/questions/20212582/将宏指定给按钮将一个按钮添加到工作表(开发人员选项卡 - >插入)https://msdn.microsoft.com/en-us/library/ bb608625。aspx右键单击按钮,选择“分配宏”选择您的宏,然后单击确定 – user1274820

回答

1

这里有一个简单的例子:

'The directory containing the files 
Const TDS_PATH = "C:\Data\TDS Search\" 

Sub openFileCopyColumn() 

'Clear our list 
Sheets("Sheet1").Range("B6:D31").Clear 

'Very basic input checking - you can always add more 
If Sheets("Sheet1").Range("C3") = "" Then 
    MsgBox("Please enter a file to search for") 
    Exit Sub 
End If 

'If the File we are searching for exists in the path 
If Dir(TDS_PATH & Sheets("Sheet1").Range("C3")) <> "" Then 

    'Disable screen updating for performance/aesthetics 
    Application.ScreenUpdating = False 

    'Open the workbook we searched for (ReadOnly) 
    Workbooks.Open TDS_PATH & Sheets("Sheet1").Range("C3"), ReadOnly:=True 

    'Copy the range we are interested in 
    ActiveWorkbook.Sheets("Sheet1").Range("A2:C16").Copy ThisWorkbook.Sheets("Sheet1").Range("B6") 

    'Close the file 
    ActiveWorkbook.Close (False) 

    'Re-enable screen updating 
    Application.ScreenUpdating = True 

Else 
    'Let the user know if the file is not found 
    MsgBox("File not found!") 
End If 
End Sub 

的TDS的Sheet1中搜索工作簿:

TDS Search

文件的工作表Sheet1 Tools1.xlsx:

​​

创建按钮并指定宏:

Button and Macro

编辑:

首先,决定你的“搜索单元” “ 将会。

我在Sheet("Sheet1")上选择了Range("C3"),上面的例子是任意的,但你的可以是任何单元格。

然后,使用上面的代码搜索并打开它(所有这些都在分配给按钮的宏中 - 请参阅屏幕截图了解如何将宏指定给按钮)。

而不是使用行:

'Copy the range we are interested in 
ActiveWorkbook.Sheets("Sheet1").Range("A2:C16").Copy ThisWorkbook.Sheets("Sheet1").Range("B6") 

如果我们要运行存储在新打开的工作簿中的宏,我们可以使用:

ActiveWorkbook.Application.Run "MacroName" 

这里有一些更多的信息:

http://www.mrexcel.com/forum/excel-questions/51660-calling-macro-another-workbook.html

+0

因此,我将已写入的代码分配给该按钮以及您在上面键入的代码...文本框插入? – Taylor

+0

如果你想TDS搜索按钮打开一个文件,那么你会想要使用像我提供的例子。如果您希望TDS Search按钮运行您的代码,您可能需要添加一些代码来检查File:字段是否为空(如果它们没有输入文件并单击您的按钮,它会运行您的代码代码 - 如果他们输入文件并单击该按钮,则会搜索该文件。)那是您想知道的吗?如果您希望能够运行两种不同的功能,则还可以添加第二个按钮。 – user1274820

+0

我的代码当前打开文件夹中的每个文件(逐个),将重要信息打印到第2,3和4列,然后将该特定文件的名称打印到第1列。我希望它能够键入文件名放入一个文本框中,然后它将搜索该文件夹以打开该特定文件,并打印该文件的重要信息。我希望我能更好地解释它。那有意义吗? @ user1274820 – Taylor

相关问题