Loop through all files in a directory - PLEASE HELP!

SamatarM

Board Regular
Joined
Nov 13, 2014
Messages
51
Hi all

The below script currently only works on 1 file at a time and I require it to run through all files in a folder location.

I need

In addition I need it to print the results on the next available row so that it does not overwrite previous data.

It also needs to return the file name in column A.

I can not seem to do this successfully at he moment.

I need it to start with the first file in a folder extract the data as specified in the script.

Print this to the final sheet on the next available row.
In addition it needs to add the file name in the first column
close the file and then move onto the next file in the folder location

Code:
Option Explicit
Option Base 1

Public Const DATASHEET As String = "MDFDATA"
Public Const TABLECONVERSIONSHEET As String = "TABLECONVERSION"
Public Const OPTIONSSHEET As String = "OPTIONS"
Public Const FinalSheet As String = "Final Sheet"
Public lByte_Order As Long                  'byte order
Public lData_Groups As Long                 'number of data groups
Public lChannel_Groups As Long              'number of channel groups
Public lChannels As Long                    'number of channels
Public lTable_offset As Long                'row offset for the conversion table sheet
'==================================================================================================
'   PARSE_MDF
'   Main function
'   Returns True if successful
'==================================================================================================
Function PARSE_MDF() As Boolean
    Dim sFile_Name As String                'MDF file name
    Dim lFile_Number As Long                'file number
    
    Dim lData_Groups_Counter As Long        'data groups counter
    Dim lChannel_Groups_Counter As Long     'channel groups counter
    Dim lChannels_Counter As Long           'channels counter
    Dim lRecords As Long                    'number of records in data block
    Dim lRecord_Length As Long              'length of record in data block
    
    Dim lData_Group_Address As Long         'data group address
    Dim lData_Address As Long               'data address
    Dim lChannel_Group_Address As Long      'Channel group address
    Dim lChannel_Address As Long            'Channel address
    
    Dim byCol As Byte                       'column counter for output
    Dim wsData_Sheet As Worksheet           'main worksheet
    Dim wsTable_Conversion_Sheet As Worksheet
    
    Dim rFirst_Signal As Range              'first signal in channel group
    Dim rLast_Signal As Range               'last signal in channel group
    Dim rSignals As Range                   'range of signal names for a channel group
    Application.EnableEvents = False
    
    lTable_offset = 0
    Set wsTable_Conversion_Sheet = Workbooks(ActiveWorkbook.Name).Worksheets(TABLECONVERSIONSHEET)
    Set wsData_Sheet = Workbooks(ActiveWorkbook.Name).Worksheets(DATASHEET)
    
    'get file name
    sFile_Name = Application.GetOpenFilename(",*.*")
    
    'file selected
    If sFile_Name <> "False" Then
        'clear old data
        wsData_Sheet.Columns.Clear
        wsTable_Conversion_Sheet.Columns.ClearContents
        
        'set headers
        wsData_Sheet.Cells(1, 1).Value = "Signal name"
        wsData_Sheet.Cells(2, 1).Value = "Data type"
        wsData_Sheet.Cells(3, 1).Value = "Lsb"
        wsData_Sheet.Cells(4, 1).Value = "Offset"
        wsData_Sheet.Cells(5, 1).Value = "Bit length"
        wsData_Sheet.Cells(6, 1).Value = "Formula ID"
        wsData_Sheet.Cells(7, 1).Value = "Formula"
        wsData_Sheet.Cells(8, 1).Value = "First Bit position"
        wsData_Sheet.Cells(9, 1).Value = "Table length"
        wsData_Sheet.Cells(10, 1).Value = "Start Row"
        
        'offset columns because of headers
        byCol = 2
        
        'get file number
        lFile_Number = FreeFile
        
        'open file
        Open sFile_Name For Binary Access Read Shared As #lFile_Number
        
            'check file integrity
            If IDBLOCK(lFile_Number) Then
                      
                'check data exists
                If HDBLOCK(lFile_Number, lData_Group_Address) Then
                    'main iteration for data groups
                    For lData_Groups_Counter = 1 To lData_Groups
                    
                        'check channel group exists
                        If DGBLOCK(lFile_Number, lData_Group_Address, lChannel_Group_Address, lData_Address) Then
                            'channel group iteration
                            For lChannel_Groups_Counter = 1 To lChannel_Groups
          
                                'get channel group data
                                Call CGBLOCK(lFile_Number, lChannel_Group_Address, lChannel_Address, lRecord_Length, lRecords)
                                'set the first signal range in this channel group
                                Set rFirst_Signal = wsData_Sheet.Cells(1, byCol)
                                
                                'channels iteration
                                For lChannels_Counter = 1 To lChannels
                                
                                    'get channel data for each channel
                                    Call CNBLOCK(lFile_Number, lChannel_Address, wsData_Sheet, byCol)
                                    
                                    'excel fudge
                                    If byCol <> 255 Then
                                        byCol = byCol + 1
                                    End If
                                    
                                Next    'lChannels_Counter
         
                                'set the last signal range in this channel group
                                Set rLast_Signal = wsData_Sheet.Cells(1, byCol - 1)
                                
                                'format divider columns
                                wsData_Sheet.Columns(byCol).ColumnWidth = 5
                                wsData_Sheet.Columns(byCol).Interior.ColorIndex = 0
                                wsData_Sheet.Columns(byCol).Interior.Pattern = xlLightUp
                                wsData_Sheet.Columns(byCol).Interior.PatternColorIndex = xlAutomatic
                                
                                'excel fudge
                                If byCol <> 255 Then
                                    'for space between channels
                                    byCol = byCol + 1
                                End If
                                
                            Next    'lChannel_Groups_Counter
                            'get range of signals to get data for
                            Set rSignals = wsData_Sheet.Range(rFirst_Signal, rLast_Signal)
                            'get signal data
                           
                        'no channel data in this data group
                        Else
                            PARSE_MDF = False
                            
                        End If
                    
                    Next    'lData_Groups_Counter
 
                'no data in MDF file
                Else
                    PARSE_MDF = False
                
                End If
            'not a MDF file
            Else
                PARSE_MDF = False
            
            End If
            
        'close file
        Close #lFile_Number
            
        'tidy up sheet
        wsData_Sheet.Rows.EntireRow.AutoFit
        wsData_Sheet.Columns.EntireColumn.AutoFit
        wsData_Sheet.Rows("2:15").EntireRow.Delete
        wsData_Sheet.Columns("A:A").EntireColumn.Delete
        wsData_Sheet.Cells.HorizontalAlignment = xlCenter
                
        'function ends normally
        PARSE_MDF = True
        
    'no file was selected
    Else
        PARSE_MDF = False
        
    End If
    Application.EnableEvents = True
    
End Function
'==================================================================================================
'   IDBLOCK
'   Gets and checks data from IDBLOCK
'   Returns True if successful
'==================================================================================================
Function IDBLOCK(lFile_Number As Long) As Boolean
    Dim sTemp As String
    Dim byTemp As Byte
    
    'get file ID
    sTemp = Space(3)
    Get lFile_Number, &H1, sTemp
    'MsgBox "File ID: " + sTemp
    If sTemp = "MDF" Then
        
        'get byte order
        Get lFile_Number, &H19, byTemp
        lByte_Order = byTemp
        Get lFile_Number, &H1A, byTemp
        lByte_Order = lByte_Order + (byTemp * (2 ^ 8))
        'MsgBox "lByte_Order: " + Hex(lByte_Order)
        If lByte_Order <> 0 Then
        
            IDBLOCK = False
            
        Else
            IDBLOCK = True
            
        End If
        
    Else
    
        IDBLOCK = False
    End If
End Function
'==================================================================================================
'   HDBLOCK
'   Gets and checks data from HDBLOCK
'   Returns True if successful
'==================================================================================================
Function HDBLOCK(lFile_Number As Long, lData_Group_Address As Long) As Boolean
    
    Dim byTemp As Byte
    
    Get lFile_Number, &H51, byTemp
    lData_Groups = byTemp
    Get lFile_Number, &H52, byTemp
    lData_Groups = lData_Groups + (byTemp * (2 ^ 8))
    'MsgBox "lData_Groups: " + CStr(lData_Groups)
    Get lFile_Number, &H45, lData_Group_Address
    'MsgBox "lData_Group_Address: " + Hex(lData_Group_Address)
                
    If lData_Groups <> 0 And lData_Group_Address <> 0 Then
        HDBLOCK = True
        
    Else
        HDBLOCK = False
                
    End If
    
End Function
'==================================================================================================
'   DGBLOCK
'   Gets and checks data from DGBLOCK
'   Returns True if successful
'==================================================================================================
Function DGBLOCK(lFile_Number As Long, lData_Group_Address As Long, lChannel_Group_Address As Long, lData_Address As Long) As Boolean
    Dim lTemp As Long
    Dim byTemp As Byte
    
    Get lFile_Number, lData_Group_Address + &H5, lTemp
    'MsgBox "Next lData_Group_Address: " + Hex(lTemp)
    
    Get lFile_Number, lData_Group_Address + &H9, lChannel_Group_Address
    'MsgBox "lChannel_Group_Address: " + Hex(lChannel_Group_Address)
    
    Get lFile_Number, lData_Group_Address + &H11, lData_Address
    'MsgBox "lData_Address: " + Hex(lData_Address)
    
    Get lFile_Number, lData_Group_Address + &H15, byTemp
    lChannel_Groups = byTemp
    Get lFile_Number, lData_Group_Address + &H16, byTemp
    lChannel_Groups = lChannel_Groups + (byTemp * (2 ^ 8))
    'MsgBox "lChannel_Groups: " + CStr(lChannel_Groups)
    lData_Group_Address = lTemp
    If lChannel_Groups <> 0 And lChannel_Group_Address <> 0 Then
        DGBLOCK = True
        
    Else
        DGBLOCK = False
            
    End If
    
End Function
'==================================================================================================
'   CGBLOCK
'   Gets and checks data from CGBLOCK
'   Returns True if successful
'==================================================================================================
Function CGBLOCK(lFile_Number As Long, lChannel_Group_Address As Long, lChannel_Address As Long, lRecord_Length As Long, lRecords As Long) As Boolean
    Dim byTemp As Byte
    
    Get lFile_Number, lChannel_Group_Address + &H9, lChannel_Address
    'MsgBox "lChannel_Address: " + Hex(lChannel_Address)
    
    Get lFile_Number, lChannel_Group_Address + &H13, byTemp
    lChannels = byTemp
    Get lFile_Number, lChannel_Group_Address + &H14, byTemp
    lChannels = lChannels + (byTemp * (2 ^ 8))
    'MsgBox "lChannels: " + CStr(lChannels)
    
    Get lFile_Number, lChannel_Group_Address + &H15, byTemp
    lRecord_Length = byTemp
    Get lFile_Number, lChannel_Group_Address + &H16, byTemp
    lRecord_Length = lRecord_Length + (byTemp * (2 ^ 8))
    'MsgBox "lRecord_Length: " + CStr(lRecord_Length)
        
    Get lFile_Number, lChannel_Group_Address + &H17, lRecords
    'MsgBox "lRecords: " + CStr(lRecords)
End Function
'==================================================================================================
'   CNBLOCK
'   Gets and checks data from CNBLOCK
'   Returns True if successful
'==================================================================================================
Function CNBLOCK(lFile_Number As Long, lChannel_Address As Long, wsData_Sheet As Worksheet, byCol As Byte) As Boolean
    Dim sSignal_Name As String
    Dim lNext_Channel_Address As Long
    Dim lConversion_Address As Long
    Dim lFirst_Data As Long
    Dim lBit_Length As Long
    Dim lData_Type As Long
    Dim byTemp As Byte
    
    Get lFile_Number, lChannel_Address + &H5, lNext_Channel_Address
    'MsgBox "lNext_Channel_Address: " + Hex(lNext_Channel_Address)
    Get lFile_Number, lChannel_Address + &H9, lConversion_Address
    'MsgBox "lConversion_Address: " + Hex(lConversion_Address)
    'signal name
    sSignal_Name = Space(32)
    Get lFile_Number, lChannel_Address + &H1B, sSignal_Name
    
    If InStr(1, sSignal_Name, "\") <> 0 Then
        sSignal_Name = Mid(sSignal_Name, 1, InStr(1, sSignal_Name, "\") - 1)
    End If
    
    wsData_Sheet.Cells(1, byCol).Value = sSignal_Name
    
    'first bit data location
    Get lFile_Number, lChannel_Address + &HBB, byTemp
    lFirst_Data = byTemp
    Get lFile_Number, lChannel_Address + &HBC, byTemp
    lFirst_Data = lFirst_Data + (byTemp * (2 ^ 8))
    
    wsData_Sheet.Cells(8, byCol).Value = lFirst_Data
    'bit length
    Get lFile_Number, lChannel_Address + &HBD, byTemp
    lBit_Length = byTemp
    Get lFile_Number, lChannel_Address + &HBE, byTemp
    lBit_Length = lBit_Length + (byTemp * (2 ^ 8))
    wsData_Sheet.Cells(5, byCol).Value = lBit_Length
    'data type
    Get lFile_Number, lChannel_Address + &HBF, byTemp
    lData_Type = byTemp
    Get lFile_Number, lChannel_Address + &HC0, byTemp
    lData_Type = lData_Type + (byTemp * (2 ^ 8))
    wsData_Sheet.Cells(2, byCol).Value = lData_Type
    Call CCBLOCK(lFile_Number, lConversion_Address, wsData_Sheet, byCol)
    
    lChannel_Address = lNext_Channel_Address
End Function
'==================================================================================================
'   CNBLOCK
'   Gets and checks data from CNBLOCK
'   Returns True if successful
'==================================================================================================
Function CCBLOCK(lFile_Number As Long, lConversion_Address As Long, wsData_Sheet As Worksheet, byCol As Byte) As Boolean
    Dim fdOffset As Double
    Dim fdLSB As Double
    Dim fdTemp As Double
    
    Dim byTemp As Byte
    
    Dim lBlock_Length As Long
    Dim lFormula_ID As Long
    Dim lTable_Length As Long
    Dim lCounter As Long
    Dim lText_Address As Long
    Dim lText_Block_Length As Long
    
    Dim sTemp As String
    Dim wsTable_Conversion_Sheet As Worksheet
    
    Set wsTable_Conversion_Sheet = Workbooks(ActiveWorkbook.Name).Worksheets(TABLECONVERSIONSHEET)
    
    sTemp = Space(2)
    Get lFile_Number, lConversion_Address + &H1, sTemp
    'MsgBox "Block Identification: " + sTemp
    
    If sTemp = "CC" Then
    
        Get lFile_Number, lConversion_Address + &H3, byTemp
        lBlock_Length = byTemp
        Get lFile_Number, lConversion_Address + &H4, byTemp
        lBlock_Length = lBlock_Length + (byTemp * (2 ^ 8))
        'MsgBox "lBlock_Length: " + CStr(lBlock_Length)
        
        Get lFile_Number, lConversion_Address + &H2B, byTemp
        lFormula_ID = byTemp
        Get lFile_Number, lConversion_Address + &H2C, byTemp
        lFormula_ID = lFormula_ID + (byTemp * (2 ^ 8))
        wsData_Sheet.Cells(6, byCol).Value = lFormula_ID
        'Vector formula style
        If lFormula_ID = 10 Then
            sTemp = Space(lBlock_Length - &H2F)
            Get lFile_Number, lConversion_Address + &H2F, sTemp
            wsData_Sheet.Cells(7, byCol).Value = sTemp
        'Vector table style
        ElseIf lFormula_ID = 12 Then
            Get lFile_Number, lConversion_Address + &H2D, byTemp
            lTable_Length = byTemp
            Get lFile_Number, lConversion_Address + &H2E, byTemp
            lTable_Length = lTable_Length + (byTemp * (2 ^ 8))
            wsData_Sheet.Cells(9, byCol).Value = lTable_Length
            
            If lTable_offset = 0 Then
                wsData_Sheet.Cells(10, byCol).Value = 1
            Else
                wsData_Sheet.Cells(10, byCol).Value = lTable_offset + 1
            End If
            
            For lCounter = 1 To lTable_Length
                
                Get lFile_Number, lConversion_Address + &H2F + (&H14 * (lCounter - 1)), fdTemp
                wsTable_Conversion_Sheet.Cells(lCounter + lTable_offset, 1).Value = fdTemp
                
                Get lFile_Number, lConversion_Address + &H37 + (&H14 * (lCounter - 1)), fdTemp
                wsTable_Conversion_Sheet.Cells(lCounter + lTable_offset, 2).Value = fdTemp
                
                Get lFile_Number, lConversion_Address + &H3F + (&H14 * (lCounter - 1)), lText_Address
                
                Get lFile_Number, lText_Address + &H3, byTemp
                lText_Block_Length = byTemp
                Get lFile_Number, lText_Address + &H4, byTemp
                lText_Block_Length = lText_Block_Length + (byTemp * (2 ^ 8))
                
                sTemp = Space(lText_Block_Length - 4)
                Get lFile_Number, lText_Address + &H5, sTemp
                wsTable_Conversion_Sheet.Cells(lCounter + lTable_offset, 3).Value = sTemp
                
            Next
            
            lTable_offset = lTable_offset + lCounter
            
        'ETAS text style
        ElseIf lFormula_ID = 65535 Then
        
        'normal LSB, offset style
        Else
           'get offset
           Get lFile_Number, lConversion_Address + &H2F, fdOffset
           wsData_Sheet.Cells(4, byCol).Value = fdOffset
           
           'get lsb
           Get lFile_Number, lConversion_Address + &H37, fdLSB
           wsData_Sheet.Cells(3, byCol).Value = fdLSB
        End If
    
        CCBLOCK = True
        
    Else
        CCBLOCK = False
    
    End If
End Function

'==================================================================================================
'   FORMULA_CONVERSION
'
'   Returns the output of the formula
'==================================================================================================
Function FORMULA_CONVERSION(lArgument As Variant, sFormula As String) As Double
    Dim fdLSB As Double
    Dim fdOffset As Double
    Dim fdExponant As Double
    
    Dim sTemp As String
    
    FORMULA_CONVERSION = 0
    
    'formula in the form n1*x+n2
    If IsNumeric(Left(sFormula, 1)) Then
    
        If InStr(1, sFormula, "*") <> 0 Then
 
            fdLSB = CDbl(Mid(sFormula, 1, InStr(1, sFormula, "*") - 1))
            
            If InStr(1, sFormula, "+") <> 0 Then
                fdOffset = CDbl(Right(sFormula, Len(sFormula) - InStr(1, sFormula, "+")))
                FORMULA_CONVERSION = (fdLSB * lArgument) + fdOffset
                
            ElseIf InStr(1, sFormula, "-") <> 0 Then
                fdOffset = CDbl(Right(sFormula, Len(sFormula) - InStr(1, sFormula, "-")))
                FORMULA_CONVERSION = (fdLSB * lArgument) - fdOffset
            
            End If
            
        End If
        
    'formula in the form (x-n2)/(2^n1)
    ElseIf Left(sFormula, 1) = "(" Then
        If InStr(1, sFormula, ")") <> 0 Then
            
            fdOffset = CDbl(Mid(sFormula, 3, InStr(1, sFormula, ")") - 3))
            If InStr(1, sFormula, "^") <> 0 Then
            
                fdExponant = CDbl(Mid(sFormula, InStr(1, sFormula, "^") + 1, Len(sFormula) - InStr(1, sFormula, "^")))
                FORMULA_CONVERSION = (lArgument + fdOffset) / (2 ^ fdExponant)
                
            End If
        End If
        
    End If
    
End Function
Function Copy()
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = Worksheets("MDFDATA")
Set pasteSheet = Worksheets("Final Sheet")
copySheet.Range("A:O").Copy
pasteSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Function
 
Last edited by a moderator:

Excel Facts

Copy formula down without changing references
If you have =SUM(F2:F49) in F50; type Alt+' in F51 to copy =SUM(F2:F49) to F51, leaving the formula in edit mode. Change SUM to COUNT.
It certainly looks like it will.

Just one questions. I have been struggling with adding any code to this script without it causing faults. How would I get this code in is it ahead of all the code as a sub function or function?

sorry I am a real newbie

Thanks
 
Upvote 0
i suppose it shd be in a standard module
when you get the name of each file in the folder what to do with that file for which you can introduce st of code or preferabl write a separate macro and write the name of the macro there
in the above code once the file is opened the macro changes the color of the range in each sheet of the workbook.
 
Upvote 0

Forum statistics

Threads
1,225,204
Messages
6,183,573
Members
453,170
Latest member
sameer98

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top