Results 1 to 12 of 12

Thread: [RESOLVED] Copying specific values from a .txt file

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Jun 2014
    Posts
    16

    Resolved [RESOLVED] Copying specific values from a .txt file

    Hey, I've attached my macro as it is now.

    The thing I want to do is search through a folder full of .txt files (with different content) and extract some information. I can manage all of it, but it does not feel very robust.
    I want a more dynamic/easier way of extracting (if there is one) the info I want, its a mixture of textinfo and numbers. And I want it reported in an excel.docx. Lets say four pieces of info from the text file, reported in a range(cells(1,1),cells(4,2)) area, with a reference in coloumn 1, and the extracted info in coloumn 2.

    Main question: In what way can I easily identify the parts I want to extract from the text files? The info I want might not be in the same place in every file, which makes my approach fail.

    All help appreciated!

    Cheers!

    Code below, and attached.
    Code:
    Sub AllWorkbooks()
    
       Dim MyFolder As String 'Path collected from the folder picker dialog
    
       Dim MyFile As String 'Filename obtained by DIR function
    
       Dim wbk As Workbook 'Used to loop through each workbook
    
    On Error Resume Next
    
    Application.ScreenUpdating = False
    
    'Opens the folder picker dialog to allow user selection
    
    With Application.FileDialog(msoFileDialogFolderPicker)
    
    .Title = "Please select a folder"
    
    .Show
    
    .AllowMultiSelect = False
    
       If .SelectedItems.Count = 0 Then 'If no folder is selected, abort
    
    MsgBox "You did not select a folder"
    
          Exit Sub
    
       End If
    
    MyFolder = .SelectedItems(1) & "\" 'Assign selected folder to MyFolder
    
    End With
    
    MyFile = Dir(MyFolder) 'DIR gets the first file of the folder
    
    'Loop through all files in a folder until DIR cannot find anymore
    
    y = 1
    Do While MyFile <> “”
    
       'Opens the file and assigns to the wbk variable for future use
    
       Set wbk = Workbooks.Open(Filename:=MyFolder & MyFile)
    
     '#########         THIS IS WHAT i WANT TO IMPROVE      ############################
    Sheets(1).Cells(2, 1).Copy              'copys the selection I'm after
    Workbooks("åpne tekstfiler.xlsm").Activate 'opens any sheet you want to store the data
    Sheets(1).Cells(y, 2).Select 'choose cell to paste
    ActiveSheet.Paste
    fx = "B" & y
    formel1 = "=MID(" & fx & ",33,10)"
    Cells(y, 1).Select
    Cells(y, 1).Formula = formel1
    Dim myval
    myval = Val(Cells(y, 1))
    y = y + 1
    wbk.Close savechanges:=True
    
    
    MyFile = Dir 'DIR gets the next file in the folder
    
    Loop
    
    'the numbers I get from the formula gives an error naming it as text or appostrophe in it... I want it to be numbers, so I do the below to fix (bettersolution?)
    
    
    Range("a:a").Copy
    Range("a:a").PasteSpecial xlPasteValues
        Application.CutCopyMode = False
    
    
    Range("J1:J17").Formula = "=Value(A1)"  'formatted as text, need to format as number
    Range("j:j").Copy
    Range("j:j").PasteSpecial xlPasteValues
        Application.CutCopyMode = False
    
    Range("a:a").Value = Range("j:j").Value
    
    Range("j:j").Clear
    
    '######################################################################################
    
    Application.ScreenUpdating = True
    
    End Sub
    Attached Files Attached Files

  2. #2
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: Copying specific values from a .txt file

    Set wbk = Workbooks.Open(Filename:=MyFolder & MyFile)
    if these are text files why open as workbooks?

    Code:
     '#########         THIS IS WHAT i WANT TO IMPROVE      ############################
    wbk.Sheets(1).Cells(2, 1).Copy              'copys the selection I'm after
    'Workbooks("åpne tekstfiler.xlsm").Activate 'opens any sheet you want to store the data
    with mainsht
       .Cells(y, 2).pastespecial
       fx = "B" & y
       formel1 = "=MID(" & fx & ",33,10)"
       'Cells(y, 1).Select
       .Cells(y, 1).Formula = formel1
    end with
    Dim myval
    myval = Val(Cells(y, 1))  ' i can not see what this is ever used for
    y = y + 1
    wbk.Close savechanges:=True    'why save changes, nothing is changed in the file?
    before the loop set a worksheet object for the target workbook like
    set mainsht = Workbooks("åpne tekstfiler.xlsm").sheets(1)

    try change the formula to
    formel1 = "=value(MID(" & fx & ",33,10))"
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  3. #3
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Copying specific values from a .txt file

    Quote Originally Posted by Arithos View Post
    Main question: In what way can I easily identify the parts I want to extract from the text files? The info I want might not be in the same place in every file, which makes my approach fail.
    Is there any identifying information stored in the rows you want to pull data from? You will need something to search for so that that needed information can be extracted. If possible, post a sample of your text file (you do not need to post all of it, just a sample that shows needed rows and unneeded rows).

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Jun 2014
    Posts
    16

    Re: Copying specific values from a .txt file

    In the attached text file, I will want this information extracted and sorted "nicely" in excel for further use.

    The Underlined information is what I want extracted:

    as an example from the first part of the text file.

    Handelsbanken INVOICE Page 1 / 1
    NORDIC CUSTODY SERVICES OSLO


    Minimum fee NOK 1 1*000.00
    1*000.00
    Total NOK
    1*000.00

    Please be informed that we will debit your account 83960235013on expiry date 7.7.




    third "part" of the text file.


    Svenska Handelsbanken AB Svenska Handelsbanken Telephone
    Registered office: Stockholming Business ID: NO 971 17 Fax 22 39 70
    Registered in the bank register Postboks 1342 VIKA +47 22 39 72
    Swedish Financial Supervisory A N-0113 Oslo SWIFT
    Business organisation number: 5 Norway HANDNOKK

    Average value Basis point Fee
    Safekeeping fee
    1 804 301 (0.0050%) 7*414.94
    7*414.94
    Transaction fee
    #528 NOK 35. 18*480.00
    18*480.00
    Transaction fee
    Repair fees #13 NOK 50. 650.00
    650.00
    Total NOK
    26*544.94



    Looks quite messy when I put it inhere, but there is a system to it, if you look in the .txt file its easier to get an overview.

    All I'm looking for is a way to extract the data directly from the text file, Searching it for the different "fee's" and I need a name.

    If necessary for the sorting you might have to split the different "parts" of the textfile?

    Am I making myself understood?
    Attached Files Attached Files

  5. #5
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Copying specific values from a .txt file

    Please clarify the attached text file structure.

    Is your attached file a single file that needs to be processed or is it an example of three different file formats where the real file would be one of the shown formats.

    I am assuming that it represents three different formats.
    Last edited by TnTinMN; Jul 7th, 2014 at 03:35 PM.

  6. #6
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Copying specific values from a .txt file

    Working on the assumption that there are three file formats ( the assumed file types are defined in the comments), I created the below code to read the text file into a Collection where each item in the collection is a line from the file. The code determines the file type.

    I am not going to write all the code and expect that you can write the code needed to find and extract the needed information based on knowing the file type and by searching the lines for key phases that identify the line that contains the phrase.

    Searching and line parsing is a basic staple file processing and should not be that difficult for you. If you need assistance understanding what I wrote, feel free to ask. The main method in the below code is the "Test" subroutine.

    VBA Code:
    1. Option Explicit
    2.  
    3. Public Enum SourceType
    4.    TypeI = 0
    5.    TypeIIA = 1
    6.    TypeIIB = 2
    7. End Enum
    8.  
    9. Sub Test()
    10.  
    11.    Dim numLines As Integer
    12.    Dim lines As Collection
    13.    Set lines = ReadAllLines(filePath:="path to file", trimLines:=True)
    14.    If lines.count > 0 Then
    15.       Dim fileType As SourceType
    16.       fileType = DetermineType(lines)
    17.      
    18.       Select Case fileType
    19.          Case SourceType.TypeI
    20. '            Stop
    21.             'process this file
    22.          Case SourceType.TypeIIA
    23. '            Stop
    24.             'process this file
    25.          Case SourceType.TypeIIB
    26. '            Stop
    27.             'process this file
    28.       End Select
    29.    End If 'lines.count > 0
    30.  
    31.  
    32. End Sub
    33.  
    34. Private Function ReadAllLines(filePath As String, Optional trimLines As Boolean = False) As Collection
    35.    Dim fso As Object
    36.    Dim txtStream As Object
    37.    
    38.    Const IOMode_ForReading As Integer = 1
    39.    Const TriState_False As Integer = 0
    40.    
    41.    Set fso = CreateObject("Scripting.FileSystemObject")
    42.    Set txtStream = fso.OpenTextFile(filePath, IOMode_ForReading, False, TriState_False)
    43.    
    44.    Dim numLines As Integer
    45.    Dim lines As New Collection
    46.    
    47.    Do While Not txtStream.AtEndOfStream
    48.       If trimLines Then
    49.          lines.Add (trim$(txtStream.ReadLine))
    50.       Else
    51.          lines.Add (txtStream.ReadLine)
    52.       End If
    53.    Loop
    54.    Set ReadAllLines = lines
    55.  
    56. End Function
    57.  
    58. Private Function DetermineType(source As Collection) As SourceType
    59.    ' Type I:
    60.       ' No real unique text.
    61.       ' What will decide if a file is TypeI is it is TypeI if it is not a TypeII file.
    62.       ' It will contain this block similar to TypeIIA
    63.          'Minimum fee                                                  NOK 1             1*000.00
    64.          '                                                                               1*000.00
    65.          '                                                          Total NOK
    66.          '                                                                               1*000.00
    67.      
    68.    ' Type II
    69.       ' All TypeII files contain a block of lines like this:
    70.       'Svenska Handelsbanken AB                Svenska Handelsbanken       Telephone
    71.       'Registered office: Stockholming         Business ID: NO 971 17      Fax 22 39 70
    72.       'Registered in the bank register         Postboks 1342 VIKA          +47 22 39 72
    73.       'Swedish Financial Supervisory A         N-0113 Oslo                 SWIFT
    74.       'Business organisation number: 5         Norway                      HANDNOKK
    75.      
    76.          ' TypeIIA files will have this block:
    77.             'Minimum fee                                                  NOK 1             1*000.00
    78.             '                                                                               1*000.00
    79.             '                                                          Total NOK
    80.             '                                                                               1*000.00
    81.          
    82.          ' TypeIIB files will have this block:
    83.             '                                     Average value      Basis point                 Fee
    84.             'Safekeeping fee
    85.             '                                        1 804 301         (0.0050%)            7*414.94
    86.             '                                                                               7 414.94
    87.             'Transaction fee
    88.             '                                              #528          NOK 35.           18*480.00
    89.             '                                                                              18*480.00
    90.             'Transaction fee
    91.             'Repair fees                                    #13          NOK 50.              650.00
    92.             '                                                                                 650.00
    93.             '                                                          Total     NOK
    94.             '                                                                              26*544.94
    95.  
    96.    Dim startTypeII As Integer
    97.    startTypeII = StartofTypeIIBlock(source)
    98.    If startTypeII <> -1 Then
    99.       'see if it contains TypeIIA block
    100.       Dim startTypeIIA As Integer
    101.       startTypeIIA = StartOfMinimumFeeBlock(source, startTypeII + 5)
    102.       If startTypeIIA = -1 Then
    103.          DetermineType = TypeIIB
    104.       Else
    105.          DetermineType = TypeIIA
    106.       End If
    107.    Else
    108.       DetermineType = TypeI
    109.    End If
    110.    
    111.    
    112.    
    113. End Function
    114.  
    115. Private Function StartofTypeIIBlock(source As Collection) As Integer
    116.    Dim ret As Integer
    117.    ret = -1 ' Default not found
    118.    
    119.    ' All TypeII files contain a block of lines like this:
    120.    'Svenska Handelsbanken AB                Svenska Handelsbanken       Telephone
    121.    'Registered office: Stockholming         Business ID: NO 971 17      Fax 22 39 70
    122.    'Registered in the bank register         Postboks 1342 VIKA          +47 22 39 72
    123.    'Swedish Financial Supervisory A         N-0113 Oslo                 SWIFT
    124.    'Business organisation number: 5         Norway                      HANDNOKK
    125.    
    126.    ' find the line starting with: "Business organisation number:"
    127.    ' assume this string only exists in this file type and will be at the start of a line.
    128.    
    129.    Dim line As String
    130.    Dim i As Integer
    131.    Dim positions() As Integer
    132.    If source.count >= 5 Then ' should be at least 5 lines
    133.        For i = 5 To source.count
    134.          line = source.Item(i)
    135.  
    136.          If Contains(line, "Business organisation number:", positions) Then
    137.             If positions(0) = 1 Then
    138.                ret = i - 4 ' 4 preceeding lines to start of block.
    139.             End If
    140.          End If
    141.    
    142.          If ret <> -1 Then Exit For
    143.       Next i
    144.    End If
    145.    
    146.  
    147.    StartofTypeIIBlock = ret
    148. End Function
    149.  
    150. Private Function StartOfMinimumFeeBlock(source As Collection, Optional startAtLine As Integer = 1) As Integer
    151.    Dim ret As Integer
    152.    ret = -1
    153.    'Minimum fee                                                  NOK 1             1*000.00
    154.    '                                                                               1*000.00
    155.    '                                                           Total     NOK
    156.    '                                                                               1*000.00
    157.    Dim line As String
    158.    Dim i As Integer
    159.    Dim positions() As Integer
    160.    If source.count >= startAtLine Then
    161.        For i = 5 To source.count
    162.          line = source.Item(i)
    163.  
    164.          If Contains(line, "Minimum fee ", positions) Then
    165.             If positions(0) = 1 And UBound(positions) = 0 Then
    166.                ' check for "NOK 1"
    167.                Dim tmp() As Integer
    168.                If Contains(line, "NOK 1", tmp) Then
    169.                   If UBound(tmp) = 0 Then ' probably have it
    170.                      ' check for 3rd line & 4th lines in block
    171.                      If source.count > (i + 3) Then
    172.                         If Contains(source.Item(i + 2), "Total     NOK", tmp) Then ' assume found it
    173.                            ret = i
    174.                         End If
    175.                      End If 'source.count > (i + 3)
    176.                  
    177.                   End If 'UBound(tmp) = 0
    178.                
    179.                End If 'Contains(line, "NOK 1", tmp)
    180.                
    181.             End If ' positions(0) = 1 And UBound(posistions) = 0
    182.          End If 'Contains(line, "Minimum fee ", positions)
    183.    
    184.          If ret <> -1 Then Exit For
    185.       Next i
    186.      
    187.    End If ' source.count >= startAtLine
    188.    StartOfMinimumFeeBlock = ret
    189. End Function
    190.  
    191. Public Function Contains(searchString As String, findString As String, positions() As Integer, Optional compare As VbCompareMethod = VbCompareMethod.vbTextCompare) As Boolean
    192.    ' positions will be filled with the start position of each occurence of findString in searchString
    193.    Dim curPos As Integer
    194.    Erase positions
    195.    Dim startPos As Integer
    196.    startPos = 1
    197.    
    198.    Dim index As Integer
    199.    Dim upper As Integer
    200.    Dim searchLen As Integer
    201.    Dim findLen As Integer
    202.    
    203.    searchLen = Len(searchString)
    204.    findLen = Len(findString)
    205.  
    206.    Do
    207.       curPos = InStr(startPos, searchString, findString, compare)
    208.       If curPos <> 0 Then
    209.          ReDim Preserve positions(0 To index)
    210.          positions(index) = curPos
    211.          index = index + 1
    212.          startPos = curPos + findLen
    213.       End If
    214.    Loop Until curPos = 0 ' Or startPos > searchLen
    215.    Contains = (index > 0)
    216. End Function

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Jun 2014
    Posts
    16

    Re: Copying specific values from a .txt file

    They are given in one big text file i'm afraid, but, it should be possible to divide it into many smaller text files? They are divided within the big file with 21 blank lines (more often then not, atleast a noticable/programmable space) so just do an

    Code:
    for 1 to endlines
    IF count(lines = "") > 15 then
    
    cut above lines, and store in new file,
    
    next
    or something?

    or just loop through the bigger file in some way?

    The formats are the ones you have chosen, might be some discrepancies but those I can amend on my own, I like your approach, like many things in VBA this one is new to me. Lovely to learn!

    However, I am struggeling to get a grasp of the code/functions you have made. How much (other then filepath) will I have to customize?

    The functions are used to determine the filetypes, or rather if a "block? then I have to customize
    Code:
          Select Case fileType
             Case SourceType.TypeI
    '            Stop
                'process this file
             Case SourceType.TypeIIA
    '            Stop
                'process this file
             Case SourceType.TypeIIB
    '            Stop
                'process this file
          End Select
       End If 'lines.count > 0
    to dertermine what is done with this block, the " 'process this file" part?

    is this the correct interpretation?
    Last edited by Arithos; Jul 8th, 2014 at 05:50 AM.

  8. #8
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Copying specific values from a .txt file

    Quote Originally Posted by Arithos View Post
    They are given in one big text file i'm afraid, but, it should be possible to divide it into many smaller text files? They are divided within the big file with 21 blank lines (more often then not, atleast a noticable/programmable space) so just do an
    Ok, I will need to re-think this a bit. Also, I just realized that I misinterpreted the file.

    The block
    HTML Code:
       Svenska Handelsbanken AB                Svenska Handelsbanken       Telephone
       Registered office: Stockholming         Business ID: NO 971 17      Fax 22 39 70
       Registered in the bank register         Postboks 1342 VIKA          +47 22 39 72
       Swedish Financial Supervisory A         N-0113 Oslo                 SWIFT
       Business organisation number: 5         Norway                      HANDNOKK
    
    appears at the bottom of the the first three pages, but is omitted on the fourth page. I originally thought that it was the start of a page.

    I guess the formfeed character after it should have given me a clue.

    Here is a pdf of the file to illustrate the pagination based on the formfeed characters. toforum.pdf

    Will there always be four pages laid-out in this order?

  9. #9

    Thread Starter
    Junior Member
    Join Date
    Jun 2014
    Posts
    16

    Re: Copying specific values from a .txt file

    There will be about 1200 lines in a file, so alot of them =) but they layout is the same for each page. Assume there are more, and they can vary, though, it should be possible to split one text file into many smaller ones yes? and store them in a folder and then go into each one an extract the information.. if that make it easier

    I've marked again the info I want to extract in a pdf toforum .pdf

  10. #10
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Copying specific values from a .txt file

    Quote Originally Posted by Arithos View Post
    There will be about 1200 lines in a file, so alot of them =) but they layout is the same for each page. Assume there are more, and they can vary, though, it should be possible to split one text file into many smaller ones yes? and store them in a folder and then go into each one an extract the information.. if that make it easier


    I've marked again the info I want to extract in a pdf
    Assuming that each page is terminated by a formfeed character (except last page), then breaking the file appart by pages is pretty easy.

    After reviewing your highlighted pdf, I have identified these items that must be extracted from each page (I assume that you just forgot to highlight the customer name on the last page).

    • Customer Name
    • One of these cases
      1. Minimum fee
      2. Itemized Fee Data (Average Value and Fee subtotal value)
        • SafeKeeping Fee
        • Transaction Fee
        • Transaction Fee/Repair Fee
    • Account Number

    Since you are doing this in Excel, is it safe to assume that the results from each page will represent a row (record) in a table?

    I will take another look at this later and prototype it out.

  11. #11
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Copying specific values from a .txt file

    Well originally I said would not write the entire parsing code, but based on my current understanding of the file format (much less tedious) I went ahead and did it anyways. The code currently store the records in an array, you should modify that to write to a worksheet.

    I tried to comment as much as possible so hopefully you will be able to follow the logic. It may seem like there is a lot of functions, but this makes it easier to write by breaking it down into smaller parts that can be debugged on their own.

    The entry point is the "test" subroutine.

    VBA Code:
    1. Option Explicit
    2.  
    3. ' the following are User Defined Types that define a record
    4. ' they must be declared at the beginning of a Module
    5. Public Type DetailedFee
    6.    AverageValue As String
    7.    Fee As Currency
    8. End Type
    9.  
    10. Public Type myRecord
    11.    Customer As String
    12.    MinimumFee As Currency
    13.    SafekeepingFee As DetailedFee
    14.    TransactionFee As DetailedFee
    15.    RepairFee As DetailedFee
    16. End Type
    17.  
    18. Public Sub test()
    19.    ExtractData ("Path to your text file")
    20. End Sub
    21.  
    22. '------------------------------------------------------------------
    23. ' Utility functions to help search strings
    24. Public Function StartsWith(sourceString As String, findString As String, Optional compare As VbCompareMethod = VbCompareMethod.vbTextCompare) As Boolean
    25.    Dim lenSource As Integer
    26.    lenSource = Len(sourceString)
    27.    Dim lenFind As Integer
    28.    lenFind = Len(findString)
    29.    If Len(findString) > Len(sourceString) Then
    30.       StartsWith = False
    31.    Else
    32.       StartsWith = (InStr(1, sourceString, findString, compare) = 1)
    33.    End If
    34. End Function ' StartsWith
    35.  
    36. Public Function Contains(sourceString As String, findString As String, positions() As Integer, Optional compare As VbCompareMethod = VbCompareMethod.vbTextCompare) As Boolean
    37.    ' positions will be filled with the start position of each occurence of findString in sourceString
    38.    Dim curPos As Integer
    39.    Erase positions
    40.    Dim startPos As Integer
    41.    startPos = 1
    42.    
    43.    Dim index As Integer
    44.    Dim upper As Integer
    45.    Dim searchLen As Integer
    46.    Dim findLen As Integer
    47.    
    48.    searchLen = Len(sourceString)
    49.    findLen = Len(findString)
    50.  
    51.    Do
    52.       curPos = InStr(startPos, sourceString, findString, compare)
    53.       If curPos <> 0 Then
    54.          ReDim Preserve positions(0 To index)
    55.          positions(index) = curPos
    56.          index = index + 1
    57.          startPos = curPos + findLen
    58.       End If
    59.    Loop Until curPos = 0 ' Or startPos > searchLen
    60.    Contains = (index > 0)
    61. End Function ' Contains
    62. '------------------------------------------------------------------
    63.  
    64. Private Sub ExtractData(filePath As String)
    65.    Dim fso As Object
    66.    Dim txtStream As Object
    67.    
    68.    Const IOMode_ForReading As Integer = 1
    69.    Const TriState_False As Integer = 0
    70.    
    71.    Set fso = CreateObject("Scripting.FileSystemObject")
    72.    Set txtStream = fso.OpenTextFile(filePath, IOMode_ForReading, False, TriState_False)
    73.    
    74.    Dim numLines As Integer
    75.    Dim lines As New Collection
    76.    Dim page As Collection
    77.    Set page = New Collection
    78.  
    79.    ' create a dynamic array to store records
    80.    ' in reality, you would write the values directly to a Worksheet
    81.    Dim records() As myRecord
    82.    ReDim records(0 To 9) ' initially set to 10 records, increase to whatever would be appropriate
    83.  
    84.    Dim endOfPage As Boolean
    85.    Dim recordcount As Integer ' need a variable to keep track of the number of pages processed
    86.                               ' each page represents one record
    87.                              
    88.    Dim line As String ' temp line storage
    89.    
    90.    Do While Not txtStream.AtEndOfStream
    91.       line = txtStream.ReadLine
    92.      
    93.       'check if we reached an end of page
    94.       If Len(line) = 1 Then
    95.          If Mid$(line, 1, 1) = vbFormFeed Then endOfPage = True
    96.       End If
    97.       If Not endOfPage Then endOfPage = txtStream.AtEndOfStream
    98.      
    99.       If endOfPage Then
    100.          records(recordcount) = ParsePage(page)
    101.          
    102.          ' make sure we have enough storage for the records, increase array storage if filled
    103.          If recordcount = UBound(records) Then
    104.             ReDim Preserve records(0 To (recordcount + 10))
    105.          End If
    106.          
    107.          recordcount = recordcount + 1
    108.          
    109.          ' clear page collection and initialize
    110.          Set page = Nothing
    111.          Set page = New Collection
    112.          endOfPage = False ' reset flag
    113.       Else
    114.          page.Add (line)
    115.       End If
    116.    Loop
    117. End Sub
    118.  
    119. Private Function ParsePage(page As Collection) As myRecord
    120.    Dim ret As myRecord
    121.    ret.Customer = GetCustomerName(page)
    122.    ret.MinimumFee = GetMinimumFee(page)
    123.    Dim detailBreakPoints() As Integer
    124.    Dim startofDetails As Integer
    125.    detailBreakPoints = GetDetailBreakPoints(page, startofDetails)
    126.    If startofDetails <> -1 Then ' block found
    127.       ret.SafekeepingFee = GetSafekeepingFee(page, detailBreakPoints, startofDetails)
    128.       ret.TransactionFee = GetTransactionFee(page, detailBreakPoints, startofDetails)
    129.       ret.RepairFee = GetRepairFee(page, detailBreakPoints, startofDetails)
    130.    End If
    131.  
    132.    ParsePage = ret
    133. End Function
    134.  
    135. Private Function GetCustomerName(page As Collection) As String
    136.    Dim ret As String
    137.    ' the customer name is in a line with the string "Fax "
    138.    ' this line is preceeded and followed by a blank line
    139.    ' example:
    140.       '
    141.       'SHB INSTITUTIONAL SALES LONDON                      Fax nrEmail ELKE01,BOWI02
    142.       '
    143.    Dim line As String
    144.    Dim positions() As Integer
    145.    Dim i As Integer
    146.    For i = 2 To page.count - 1 ' start at line 2 because the search criteria include a blank line before the sought line
    147.                                ' end at 1 less than the number of lines due to a blank line must follow the sought line
    148.       If Contains(page.Item(i), "Fax ", positions) Then
    149.          ' check for the preceeding and following blank lines using the length of the line
    150.          If Len(page.Item(i - 1)) = 0 And Len(page.Item(i + 1)) = 0 Then
    151.             ' use the last entry in positions in case the customer name includes "Fax "
    152.             Dim lastPos As Integer
    153.             lastPos = positions(UBound(positions))
    154.             If lastPos > 1 Then
    155.                ret = trim$(Mid$(page.Item(i), 1, lastPos - 1))
    156.                Exit For
    157.             End If ' lastPos > 1
    158.          End If ' Len(page.Item(i - 1)) = 0 And Len(page.Item(i + 1)) = 0
    159.       End If 'Contains("Fax ", page.Item(i), positions)
    160.    Next i
    161.    
    162.    GetCustomerName = ret
    163. End Function
    164.  
    165. Private Function GetMinimumFee(page As Collection) As Currency
    166.    Dim ret As Currency
    167.    ' the line will look like this
    168.    'Minimum fee                                                  NOK 1             1*000.00
    169.    Const NOK1 As String = "NOK 1"
    170.    
    171.    Dim positions() As Integer
    172.    Dim i As Integer
    173.    For i = 1 To page.count
    174.       If StartsWith(trim$(page.Item(i)), "Minimum fee ") Then
    175.          If Contains(page.Item(i), NOK1, positions) Then
    176.             If UBound(positions) = 0 Then
    177.                Dim strNum As String
    178.                ' get everything after NOK 1
    179.                strNum = Mid$(page.Item(i), positions(0) + Len(NOK1))
    180.                ret = GetCurrencyValue(strNum)
    181.                Exit For
    182.             End If ' UBound(positions) = 0
    183.          End If ' Contains(page.Item(i), NOK1, positions)
    184.       End If ' StartsWith(page.Item(i), "Minimum fee ")
    185.    Next i
    186.    GetMinimumFee = ret
    187. End Function
    188.  
    189. Private Function GetDetailBreakPoints(page As Collection, startofDetails As Integer) As Integer()
    190.    Dim ret(0 To 1) As Integer
    191.    startofDetails = -1 ' used to signal not found
    192.  
    193.    '                                     Average value      Basis point                 Fee
    194.    Const Average_value As String = "Average value"
    195.    Const Basis_point As String = "Basis point"
    196.    
    197.    Dim positions() As Integer
    198.    Dim i As Integer
    199.    For i = 1 To page.count
    200.       If StartsWith(LTrim$(page.Item(i)), Average_value) Then
    201.          If Contains(page.Item(i), Basis_point, positions) Then
    202.             If Contains(page.Item(i), "Fee", positions) Then
    203.                ret(0) = InStr(1, page.Item(i), Average_value, vbTextCompare) + Len(Average_value)
    204.                ret(1) = InStr(1, page.Item(i), Basis_point, vbTextCompare) + Len(Basis_point)
    205.                startofDetails = i + 1
    206.             End If ' Contains(page.Item(i), "Fee", positions)
    207.          End If ' Contains(page.Item(i), "Basis point", positions)
    208.       End If ' StartsWith(page.Item(i), "Average value")
    209.    Next i
    210.    GetDetailBreakPoints = ret
    211. End Function
    212.  
    213. Private Function GetSafekeepingFee(page As Collection, detailBreakPoints() As Integer, startofDetails As Integer) As DetailedFee
    214.    Dim ret As DetailedFee
    215.    '                                     Average value      Basis point                 Fee
    216.    'Safekeeping fee
    217.    '                                      384 196 208.        (0.0070%)            2*210.44
    218.    '                                                                               2*210.44
    219.    Dim positions() As Integer
    220.    Dim i As Integer
    221.    For i = startofDetails To page.count
    222.       If LTrim$(page.Item(i)) = "Safekeeping fee" Then
    223.          If i < page.count Then
    224.             ret.AverageValue = trim$(Mid$(page.Item(i + 1), 1, detailBreakPoints(0)))
    225.             Dim strNum As String
    226.             strNum = Mid$(page.Item(i + 1), detailBreakPoints(1))
    227.             ret.Fee = GetCurrencyValue(strNum)
    228.          End If
    229.       End If ' page.Item(i) = "Safekeeping fee"
    230.    Next i
    231.    GetSafekeepingFee = ret
    232. End Function
    233.  
    234. Private Function GetTransactionFee(page As Collection, detailBreakPoints() As Integer, startofDetails As Integer) As DetailedFee
    235.    Dim ret As DetailedFee
    236.  
    237.    '                                     Average value      Basis point                 Fee
    238.    'Transaction fee
    239.    '                                              #144          NOK 75.           10*800.00
    240.    '                                                                              10*800.00
    241.    Dim positions() As Integer
    242.    Dim i As Integer
    243.    For i = startofDetails To page.count
    244.       If LTrim$(page.Item(i)) = "Transaction fee" Then
    245.          If i < page.count Then
    246.             ret.AverageValue = trim$(Mid$(page.Item(i + 1), 1, detailBreakPoints(0)))
    247.             Dim strNum As String
    248.             strNum = Mid$(page.Item(i + 1), detailBreakPoints(1))
    249.             ret.Fee = GetCurrencyValue(strNum)
    250.          End If
    251.       End If ' page.Item(i) = "Transaction fee"
    252.    Next i
    253.    GetTransactionFee = ret
    254. End Function
    255.  
    256. Private Function GetRepairFee(page As Collection, detailBreakPoints() As Integer, startofDetails As Integer) As DetailedFee
    257.    Dim ret As DetailedFee
    258.    '                                     Average value      Basis point                 Fee
    259.    'Transaction fee
    260.    'Repair fees                                     #7         NOK 150.            1*050.00
    261.    '                                                                               1*050.00
    262.    Dim positions() As Integer
    263.    Dim i As Integer
    264.    For i = startofDetails To page.count
    265.       If LTrim$(page.Item(i)) = "Transaction fee" Then
    266.          If i < page.count Then
    267.             Dim line As String
    268.             line = page.Item(i + 1)
    269.             If StartsWith(LTrim$(line), "Repair fees") Then
    270.                line = Replace$(line, "Repair fees", Space$(Len("Repair fees")))
    271.                ret.AverageValue = trim$(Mid$(line, 1, detailBreakPoints(0)))
    272.                Dim strNum As String
    273.                strNum = Mid$(line, detailBreakPoints(1))
    274.                ret.Fee = GetCurrencyValue(strNum)
    275.             End If
    276.            
    277.  
    278.          End If
    279.       End If ' page.Item(i) = "Safekeeping fee"
    280.    Next i
    281.    GetRepairFee = ret
    282. End Function
    283.  
    284. Private Function GetCurrencyValue(strNumber As String) As Currency ' helper function for converting string to currency
    285.    Dim tmp As String
    286.    ' remove all the spaces (" ") from the string
    287.    tmp = Replace$(strNumber, " ", "")
    288.    ' the values from the text file like: "1*000.00" appear to have a space in them
    289.    ' however it is not a space.  It has an ASCII value of 160, so need to strip that as well
    290.    ' at least for the Minimum Value pages
    291.    tmp = Replace(tmp, Chr$(160), "")
    292.    GetCurrencyValue = CCur(tmp)
    293. End Function

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Jun 2014
    Posts
    16

    Re: Copying specific values from a .txt file

    yes, it does work I just had to add this:

    Code:
    tmp = Replace(tmp, Chr$(160), "")
    tmp = Replace(tmp, ".", ",")
    Since I got a "Type mismatch" error, now the whole thing runs tho.

    I can see the stored records at the end of the "Sub ExtractData", it only contains data from the first page tho. but as "line" its already captured the next pages "customer". after this I should "continue" in the test subroutine to store the data where I want it? then it will continue to the next page?

    Per now it just ends if I run it, so there is Some customization I have to do, I'm just trying to get a decent understanding of how you've built up your code Its abit tricky to get a grasp of what you've done (love youre comments tho, VBA for dummies approach, I like


    Q1: is records stored as a three-dimensional array?

    (And yes, you hva the right understanding of the buildup of the data.)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width