×
INTELLIGENT WORK FORUMS
FOR ENGINEERING PROFESSIONALS

Log In

Come Join Us!

Are you an
Engineering professional?
Join Eng-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Eng-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

Automating Steps
2

Automating Steps

Automating Steps

(OP)
I've got about 70 Excel workbooks.  Each one has the same 5 columns of data (generated by a computer) and the name of the worksheet is the meter number.

I open the file, add a column "A", double click on the sheet name, hit <cntl> "C", move to cell A2, hit <cntl> "V", hit <cntl> "C", move over to cell B2, hit <end> and the down arrow, move over to cell "A596" (or whatever it is), hold down the <shift> key, hit <end> and the up arrow, the move the cursor down to "A3" and hit <enter>.  Then I put the cursor on "A2", hold the <shift> key down and go to the end of the data ("F596" or something like that) and hit <cntl> "C".  Finally I go to an aggregate workbook and put the cursor on the next blank "A" cell ("A2" the first time, "A598" the second, etc.) and hit <enter>.  Then I save the first file and close it.

Repeating this 70 times is more than a touch tedious.  Can anyone think of a reasonable way to automate it?  When I tried to record a macro, it didn't understand the double click on the sheet name step and crashed.

David

RE: Automating Steps

2
I can't follow what you are doing.

What do you have, and what do you want to end up with?

RE: Automating Steps

(OP)
What I have is 5 columns of hourly gas measurement data for each of 70 meters.  I need to be able to syncronize all the meters across a time stamp (I need to be able to compare what the wells were making at noon on June 15 to what was sold at noon on June 15).  

To do that I have to add a column for the meter number, populate it, and then load all the meters into an access database.  The sheet (both the worksheet name and the file name) contain the meter number that I need.  I want to automate the process of extracting the meter number and then populating it on the rows.

David

RE: Automating Steps

The sheet name code should look something like this:

    SheetName = Sheets(1).Name
    Range("A2").Select
    ActiveSheet.Paste

I double clicked and copied the sheet name in the macro recorder without any problems, but the recorded code won't work in this specific case because it (the recorder) already knows the name of the sheet, and recorded this:

    Sheets("test").Select
    Sheets("test").Name = "test"
    Range("A2").Select
    ActiveSheet.Paste

Nonetheless, you can directly address a single-sheet workbook directly through the sheet index number as in the first snippet of code.

After that, you'd still need to wrap a loop around the code and come up with a way to automatically open each sheet that you need.  You might check on Doug Jenkins' site and see if there's already some code for that.  I know that the subject of accessing files in a folder has come up at least a couple of times in the past couple of years.

TTFN

FAQ731-376: Eng-Tips.com Forum Policies
Chinese prisoner wins Nobel Peace Prize

RE: Automating Steps

Try this:

CODE

'32-bit API declarations
Declare Function SHGetPathFromIDList Lib "shell32.dll" _
  Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long

Declare Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long

Public Type BROWSEINFO
    hOwner As Long
    pidlRoot As Long
    pszDisplayName As String
    lpszTitle As String
    ulFlags As Long
    lpfn As Long
    lParam As Long
    iImage As Long
End Type



Public Function GetDirectory(Optional Msg) As String
    Dim bInfo As BROWSEINFO
    Dim path As String
    Dim r As Long, x As Long, pos As Long
 
'   Root folder = Desktop
    bInfo.pidlRoot = 0&

'   Title in the dialog
    If IsMissing(Msg) Then
        bInfo.lpszTitle = "Select a folder."
    Else
        bInfo.lpszTitle = Msg
    End If
    
'   Type of directory to return
    bInfo.ulFlags = &H1

'   Display the dialog
    x = SHBrowseForFolder(bInfo)
    
'   Parse the result
    path = Space$(512)
    r = SHGetPathFromIDList(ByVal x, ByVal path)
    If r Then
        pos = InStr(path, Chr$(0))
        GetDirectory = Left(path, pos - 1)
    Else
        GetDirectory = ""
    End If
End Function
Sub MashFiles()
Dim oPath As String
Dim FileArray() As String
Dim oFileName As String
Dim NameNumShtRev As String
Dim i As Long
Dim myxlapp As Object
Dim usedrows As Long
Dim DestinationFile As String
Dim DestinationFolder As String
Dim MasterIndex As Excel.Workbook
Dim MasterSheet As Excel.Worksheet
Dim PartIndex As Excel.Workbook
Dim PartSheet As Excel.Worksheet


'Select the path containing the files to process
oPath = GetDirectory("Select the folder containing the files to process")
If oPath = "" Then
MsgBox "A folder was not selected"
Exit Sub
End If
'Set up a file to hold the composite
DestinationFile = InputBox("Name for Destination Spreadsheet")
If Right(DestinationFile, 4) <> ".xls" Then DestinationFile = DestinationFile & ".xls"

DestinationFolder = GetDirectory("Select a folder for the Destination Spreadsheet")

'open an Excel spreadsheet
Set myxlapp = CreateObject("Excel.Application")
Set MasterIndex = myxlapp.Workbooks.Add
Set MasterSheet = MasterIndex.Worksheets(1)
myxlapp.Visible = True

' Get the names of .xls files in oPath into an array.
ReDim FileArray(1 To 10000) 'A number larger the expected number of files

xlsName = Dir(oPath & "\*.xls")
Count = 0
Do Until xlsName = ""    ' Start the loop.
    Count = Count + 1
    ReDim Preserve FileArray(1 To Count)
    FileArray(Count) = xlsName
    xlsName = Dir ' Get next entry.
 Loop

For i = 1 To UBound(FileArray)
fullfilename = oPath & "\" & FileArray(i)
Set PartIndex = myxlapp.Workbooks.Open(fullfilename)
Set PartSheet = PartIndex.Sheets(1)
PartSheet.Columns("A:A").Insert shift:=xlToRight
For r = 1 To LastRow(PartSheet)
PartSheet.Cells(r, 1).Value = PartSheet.Name
Next r
PartSheet.UsedRange.Copy
MasterSheet.Range("A1").Cells(LastRow(MasterSheet) + 1, 1).PasteSpecial
PartIndex.Save
PartIndex.Close
Next i
MasterIndex.SaveAs (DestinationFolder & "\" & DestinationFile)
End Sub


Public Function LastRow(MySheet As Excel.Worksheet)
LastRow = MySheet.UsedRange.Rows.Count + MySheet.UsedRange.Row - 1
End Function
Frustratingly non-trivial.  But some good exercise.
 

RE: Automating Steps

(OP)
WOW.  I hope most of that was code you had laying around.  

I copied it into a worksheet, but the "Function" line at the top won't compile (the rest was fine after I got rid of a bunch of "end" statements that got inserted).  It highlights the "Lib" and gives me a pop-up box with "Compile error:  Expected: end of statement" which I'm taking to mean that I'm missing a library or a path to a library.

Is this just a bone head noobie mistake or am I probably missing something?  I learned my first programing language in 1978 and have learned 10 since, but I find myself looking at code a couple of times a year and the new stuff packs so much functionality into a single word that debugging can be a challenge.

David

RE: Automating Steps

I've need to do similar assimilation tasks before, so yea, most of that was on hand, and most of the rest was found on the web.

Start with an empty workbook.

Alt-F11 to open the VBA editor.

In the VBA editor screen select Insert from the top menu, then select Module.

Copy the code exactly as it appears above into the empty module.

Go back to the Excel screen.

Hit Alt-F8 and select "MashFiles" and click run.

Should run.

RE: Automating Steps

(OP)
I started over and did your steps exactly and still get the compile error on the "Lib" step in the first non-comment line.  If I comment out the first two lines, it fails at the first call.

David

RE: Automating Steps

Try this.  In the VBA Editor's Tools menu, click References... scroll down to "Microsoft Shell Controls And Automation" and select it.

RE: Automating Steps

(OP)
Same error.  The window at the bottom of the References page says "Location:  C:\WINDOWS\SYSTEM\SHELL32.dll" just like you'd expect from the line of code that is red.  I closed excel a couple of times (even did an <alt> <cntl> <delete> and deleted the Excel.exe process after it said it was closed.  No joy.

David

RE: Automating Steps

And if that didn't work then try this version.  It uses a slightly different way, without the API calls, to browse for folders.

CODE

Function BrowseForFolder(Optional Openat As Variant, Optional prompt As String) As Variant
     'Function purpose:  To Browser for a user selected folder.
     'If the "OpenAt" path is provided, open the browser at that directory
     'NOTE:  If invalid, it will open at the Desktop level
     
    Dim ShellApp As Object
     
     'Create a file browser window at the default folder
    Set ShellApp = CreateObject("Shell.Application"). _
    BrowseForFolder(0, prompt, 0, Openat)
     
     'Set the folder to that selected.  (On error in case cancelled)
    On Error Resume Next
    BrowseForFolder = ShellApp.self.path
    On Error GoTo 0
     
     'Destroy the Shell Application
    Set ShellApp = Nothing
     
     'Check for invalid or non-entries and send to the Invalid error
     'handler if found
     'Valid selections can begin L: (where L is a letter) or
     '\\ (as in \\servername\sharename.  All others are invalid
    Select Case Mid(BrowseForFolder, 2, 1)
    Case Is = ":"
        If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
    Case Is = "\"
        If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
    Case Else
        GoTo Invalid
    End Select
     
    Exit Function
     
Invalid:
     'If it was determined that the selection was invalid, set to False
    BrowseForFolder = False
     
End Function

Sub MashFiles()
Dim oPath As String
Dim FileArray() As String
Dim oFileName As String
Dim NameNumShtRev As String
Dim i As Long
Dim myxlapp As Object
Dim usedrows As Long
Dim DestinationFile As String
Dim DestinationFolder As String
Dim MasterIndex As Excel.Workbook
Dim MasterSheet As Excel.Worksheet
Dim PartIndex As Excel.Workbook
Dim PartSheet As Excel.Worksheet


'Select the path containing the files to process
oPath = GetDirectory(, "Select the folder containing the files to process")
If oPath = "" Then
MsgBox "A folder was not selected"
Exit Sub
End If
'Set up a file to hold the composite
DestinationFile = InputBox("Name for Destination Spreadsheet")
If Right(DestinationFile, 4) <> ".xls" Then DestinationFile = DestinationFile & ".xls"

DestinationFolder = GetDirectory(, "Select a folder for the Destination Spreadsheet")

'open an Excel spreadsheet
Set myxlapp = CreateObject("Excel.Application")
Set MasterIndex = myxlapp.Workbooks.Add
Set MasterSheet = MasterIndex.Worksheets(1)
myxlapp.Visible = True

' Get the names of .xls files in oPath into an array.
ReDim FileArray(1 To 10000) 'A number larger the expected number of files

xlsName = Dir(oPath & "\*.xls")
Count = 0
Do Until xlsName = ""    ' Start the loop.
    Count = Count + 1
    ReDim Preserve FileArray(1 To Count)
    FileArray(Count) = xlsName
    xlsName = Dir ' Get next entry.
 Loop

For i = 1 To UBound(FileArray)
fullfilename = oPath & "\" & FileArray(i)
Set PartIndex = myxlapp.Workbooks.Open(fullfilename)
Set PartSheet = PartIndex.Sheets(1)
PartSheet.Columns("A:A").Insert shift:=xlToRight
For r = 1 To LastRow(PartSheet)
PartSheet.Cells(r, 1).Value = PartSheet.Name
Next r
PartSheet.UsedRange.Copy
MasterSheet.Range("A1").Cells(LastRow(MasterSheet) + 1, 1).PasteSpecial
PartIndex.Save
PartIndex.Close
Next i
MasterIndex.SaveAs (DestinationFolder & "\" & DestinationFile)
End Sub


Public Function LastRow(MySheet As Excel.Worksheet)
LastRow = MySheet.UsedRange.Rows.Count + MySheet.UsedRange.Row - 1
End Function

Public Function GetDirectory(Optional Openat As Variant, Optional prompt As String) As String
GetDirectory = BrowseForFolder(Openat, prompt)
End Function

RE: Automating Steps

(OP)
Thanks, I'll try it in the morning, been a long day.

David

RE: Automating Steps

(OP)
Worked PERFECTLY.  Thank you so much (sorry I can only give you one star in a thread).

David

RE: Automating Steps

David - I've taken care of your one star problem....gave 'em  one myself.  

Way to go MJ.

Regards,
Qshake
pipe
Eng-Tips Forums:Real Solutions for Real Problems Really Quick.
 

RE: Automating Steps

Glad it worked out.  I enjoyed the brain exercise.

RE: Automating Steps

Cleaned up a bit.

Broke the file name processing out into a Function.
Dimensioned all the variables used and only the variables used.

Should be tolerant of having other than .xls files in the process directory. (not tested)

CODE

Function BrowseForFolder(Optional OpenAt As Variant, Optional Prompt As String) As String
     'Function purpose:  To Browse for a user selected folder.
     'If the "OpenAt" path is provided, open the browser at that directory
     'If the "Promp" is provided it will appear below the dialog header bar.
     'NOTE:  If invalid, it will open at the Desktop level
     
    Dim ShellApp As Object
     
     'Create a file browser window at the default folder
    Set ShellApp = CreateObject("Shell.Application"). _
    BrowseForFolder(0, Prompt, 0, OpenAt)
     
     'Set the folder to that selected.  (On error in case cancelled)
    On Error Resume Next
    BrowseForFolder = ShellApp.self.Path
    On Error GoTo 0
     
     'Destroy the Shell Application
    Set ShellApp = Nothing
     
     'Check for invalid or non-entries and send to the Invalid error
     'handler if found
     'Valid selections can begin L: (where L is a letter) or
     '\\ (as in \\servername\sharename.  All others are invalid
    Select Case Mid(BrowseForFolder, 2, 1)
    Case Is = ":"
        If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
    Case Is = "\"
        If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
    Case Else
        GoTo Invalid
    End Select
     
    Exit Function
     
Invalid:
     'If it was determined that the selection was invalid, set to False
    BrowseForFolder = False
     
End Function


Public Function GetFileNames(oPath As String, Optional fExt As String) As String()

'Function Purpose:  Returns an array of the file names in the oPath directory.
'If the optional fExt is provided only files matching the extension are returned.
'If fExt is not provided then all files are returned.

Dim FileArray() As String
Dim fname As String
Dim SlashExt As String
Dim count As Integer

If fExt <> "" Then
    If Left(fExt, 1) = "." Then fExt = Right(fExt, Len(fExt) - 1) 'Allows fExt to be specified with or without "."
    SlashExt = "\*." & fExt
    
    Else
    SlashExt = "\*.*" 'Set extension to all if option fExt is not provided
    
End If

ReDim FileArray(1 To 2)

fname = Dir(oPath & SlashExt) 'Get first file name
count = 0
Do Until fname = ""    ' Start the loop.
    count = count + 1
    ReDim Preserve FileArray(1 To count)
    FileArray(count) = fname
    fname = Dir ' Get next entry.
 Loop
GetFileNames = FileArray
End Function

Public Function LastRow(MySheet As Excel.Worksheet) As Integer
LastRow = MySheet.UsedRange.Rows.count + MySheet.UsedRange.Row - 1
End Function

Sub MashFiles()

'Procedure Purpose:  Consolidate data from multiple spreadheets into a single spreadsheet.
'Works only with ActiveWorkBook.Sheets(1)
'For each of the multiple spreadsheets ActiveWorkBook.Sheets(1).Name is inserted into Column A of the consolidated sheet.

Dim aPath As String
Dim FileArray() As String
Dim i As Long
Dim r As Integer
Dim myxlapp As Object
Dim DestinationFile As String
Dim DestinationFolder As String
Dim MasterIndex As Excel.Workbook
Dim MasterSheet As Excel.Worksheet
Dim PartIndex As Excel.Workbook
Dim PartSheet As Excel.Worksheet


'Select the path containing the files to process and load .xls files into an array
aPath = BrowseForFolder(, "Select Folder with Files for Processing")
FileArray = GetFileNames(aPath, "xls")

'Set up a file to hold the composite
DestinationFile = InputBox("Name for Destination Spreadsheet")
If Right(DestinationFile, 4) <> ".xls" Then DestinationFile = DestinationFile & ".xls"
DestinationFolder = BrowseForFolder(, "Select a folder for the Destination Spreadsheet")

'open an Excel spreadsheet
Set myxlapp = CreateObject("Excel.Application")
Set MasterIndex = myxlapp.Workbooks.Add
Set MasterSheet = MasterIndex.Worksheets(1)
myxlapp.Visible = True

'Run though each file and do stuff
Application.ScreenUpdating = False
For i = 1 To UBound(FileArray)
    fullfilename = aPath & "\" & FileArray(i)
    Set PartIndex = myxlapp.Workbooks.Open(fullfilename)
    Set PartSheet = PartIndex.Sheets(1)
    PartSheet.Columns("A:A").Insert shift:=xlToRight
        For r = 1 To LastRow(PartSheet)
            PartSheet.Cells(r, 1).Value = PartSheet.Name
        Next r
    PartSheet.UsedRange.Copy
    MasterSheet.Range("A1").Cells(LastRow(MasterSheet) + 1, 1).PasteSpecial
    PartIndex.Save
    PartIndex.Close
Next i
MasterIndex.SaveAs (DestinationFolder & "\" & DestinationFile)
Application.ScreenUpdating = True
End Sub

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Eng-Tips Forums free from inappropriate posts.
The Eng-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Eng-Tips forums is a member-only feature.

Click Here to join Eng-Tips and talk with other members!


Resources

White Paper - Effects of AIA Quick Guide to UL 489 or UL 1077
The function of a circuit breaker is to provide overload (thermal) and short-circuit (magnetic) protection to a circuit and its downstream components. A circuit breaker functions like an airbag in a car, protecting circuit components and people by tripping the circuit to interrupt the current flow if it detects a fault condition in the control system. Download Now
White Paper - Guide to Integrate Large-Format Additive
As with any new technology, getting into large-format 3D printing begins with investigation. The first question may be a simple one: what does “large-format” mean? For 3D printers, “large” is a relative term. Many extrusion-based (FFF) 3D printers are referred to as desktop machines, because they fit on table space. Some of these have very respectable build volumes – but when it comes to “large-format,” the machines will need their own dedicated floor space. Large-format 3D printers have significant build volumes and are most often found in professional settings, like manufacturing facilities and R&D centers. Download Now

Close Box

Join Eng-Tips® Today!

Join your peers on the Internet's largest technical engineering professional community.
It's easy to join and it's free.

Here's Why Members Love Eng-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close