-2

I have a sheet that has names, SSNs and 4 columns filled with the following values: S, MB, B.

For said columns I wish to replace S with the number 4, MB with the number 3 and B with the number 2.

Sub replace()
    Dim str1, str2, str3, filename, pathname As String
    Dim i As Integer

    str1 = "MB"
    str2 = "B"
    str3 = "S"
    filename = "p"
    pathname = ActiveWorkbook.Path
    i = 1

    Do While filename <> ""
        Set wb = Workbooks.Open(pathname & filename + i)
        DoWork wb
        wb.Close SaveChanges:=True
        filename = Dir()
    Loop

End Sub

Sub DoWork(wb As Workbook)
    With wb

    End With
End Sub

In the function DoWork, how do I create a loop to replace each of the values?

Community
  • 1
  • 1
CodeTrooper
  • 1,890
  • 6
  • 32
  • 54
  • 1
    To get started, use the Macro Recorder to do some of the replacements. Then you'll have some code to start with, and you can read through [avoiding using `.Select`](http://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba-macros). Then, look up how to loop through multiple excel files and see if you can feather that code in. When you have something put together, then come back and ask for help where you're stuck. – BruceWayne Jun 10 '16 at 17:01
  • str1, str2 and str3 aren't going to hold their variables when the program goes into the DoWork sub, as they are local to the replace sub only. You need to dim them at the top of the module, outside any subs in order for all subs to recognise their values. – Chris Melville Jun 10 '16 at 17:17

2 Answers2

0

I mostly agree with Michael--to learn the most, you should get started on your own, and come back with more specific questions. However, I am looking to reach 50 rep so I will pander to you. But do please try to go through the code and understand it.

Your name suggests you are a programmer, so the concepts we make use of should be familiar. I like to work from the inside out, so here goes:

here are my variables:

Dim sFileName   As String
Dim sFilePath   As String
Dim wbBook      As Excel.Workbook
Dim i           As Double
Dim wsSheet     As Excel.Worksheet
Dim rRange      As Range
Dim c           As Range
Dim dReplace    As Double

At the core, you'll want a select case statement to read each cell and decide what the new value should be. Then you will assign the new value to the cell:

Select Case c.value 'c being the cell we are currently examining
    Case "S"
        dReplace = 4
    Case "M"
        dReplace = 3
    Case "B"
        dReplace = 2
    Case Else
        'Assuming you should only encounter the above values, 
        'then anything else is an error
        '.assert false will stop the code, or you can replace 
        'with more refined error handling
        Debug.Assert False
 End Select
 c.value = dReplace

Around that you'll want a for each loop to define the current cell and iterate through all the cells in the range you specify for that particular worksheet:

set rRange = wsSheet.Range("C2:E5000") 'Customize to your range
for each c in rRange.Cells

    '...

next

Next level up is the for next loop to iterate through all the worksheets in the current file:

For i = 1 To 30
    If wbBook.Sheets(i).Name = "" Then
        GoTo NextOne
    End If

    Set wsSheet = wbBook.Sheets(i)

    '...

NextOne:
Next i

The if then statement at the top prevents an error if there are fewer than 30 worksheets in a workbook. If the number of sheets per file varies then this will be useful, if the number is fixed, just adjust the loop to stop and the right spot. Of course, this assumes your workbooks have information on multiple sheets. If not skip the loop altogether.

I'm sure many will criticize my use of goto, but since VBA loops lack a continue command, this is the workaround I employ.

Around that you'll want another iterator to loop through your multiple files. Assuming they are all in the same folder, you can use the Dir() function to grab the file names one-by-one. You give it the file path and (optionally) the file type, and it will return the first file name it finds that meets your cirteria. Run it again and it returns the second file name, etc. Assign that to a string variable, then use the file path plus the file name to open the workbook. Use a do loop to keep going until runs out of files:

sFilePath = "C:\Your File Path Here\"
sFileName = Dir(sFilePath & "*.xlsx")

Do Until sFileName = ""

    Set wbBook = Workbooks.Open(sFilePath & sFileName)

    '...

    wbBook.Save
    wbBook.Close
    sFileName = Dir()

Loop

Now Put it all together:

Sub ReplaceLetterCodewithNumberCode()
    Dim sFileName   As String
    Dim sFilePath   As String
    Dim wbBook      As Excel.Workbook
    Dim i           As Double
    Dim wsSheet     As Excel.Worksheet
    Dim rRange      As Range
    Dim c           As Range
    Dim dReplace    As Double

    Application.ScreenUpdating = False

    sFilePath = "C:\Your File Path Here\"
    sFileName = Dir(sFilePath & "*.xlsx")

    Do Until sFileName = ""

        Set wbBook = Workbooks.Open(sFilePath & sFileName)

        For i = 1 To 30
            If wbBook.Sheets(i).Name = "" Then
                GoTo NextOne
            End If

            Set wsSheet = wbBook.Sheets(i)
            Set rRange = wsSheet.Cells("C2:E5000") 'Customize to your range. Assumes the range will be the same

            For Each c In rRange.Cells
                Select Case c.value 'c being the cell we are currently examining
                    Case "S"
                        dReplace = 4
                    Case "M"
                        dReplace = 3
                    Case "B"
                        dReplace = 2
                    Case Else
                        'Assuming you should only encounter the above values,
                        'then anything else is an error
                        '.assert false will stop the code, or you can replace
                        'with more refined error handling
                        Debug.Assert False
                 End Select
                 c.value = dReplace
            Next
NextOne:
        Next i

        wbBook.Save
        wbBook.Close
        sFileName = Dir()

    Loop

    'Clean up
    Set wbBook = Nothing
    Set wsSheet = Nothing
    Set rRange = Nothing
    Set c = Nothing
    Application.ScreenUpdating = True

End Sub
jlookup
  • 66
  • 1
  • 6
  • @codeninja In response to the code you posted, you could use the interior of my code, starting with {for i = ... next i} in DoWork – jlookup Jun 10 '16 at 18:04
  • @codeninja also, when calling a sub or function be sure to enclose your arguments in parentheses, ie {DoWork (wb)}. – jlookup Jun 10 '16 at 18:06
-1

I'll provide a high level explanation of this; implementation will be up to you. You'll start with a crawler to open all of these files one by one (a google search should help you with this). I'm not exactly sure how your sheets are organized but the general idea is to open each sheet and perform the action, so you'll need a list of filenames/paths or do it sequentially. Then once inside the file assuming the structure is the same of each you'll grab the column and input the appropriate value then save and close the file. If you're looking for how to open the VBA editor go to options and enable the Developer tab. This is a good beginner project and while you may struggle you'll learn a lot in the process.