Consulting

Results 1 to 8 of 8

Thread: Loop through All worksheets and change to Proper case

  1. #1
    VBAX Regular
    Joined
    Mar 2022
    Posts
    20
    Location

    Loop through All worksheets and change to Proper case

    Hello All,

    I am once again struggling with looping through all worksheets, when the code to run is beyond very basic. I have the code below that works great on whatever is the active worksheet to change anything in Column A to Proper Case
    Sub ProperCase()
    Dim rng As Range
        For Each rng In Range("A2", [a65536].End(xlUp)) 'Start the VBA loop
        rng = StrConv(rng.Text, vbProperCase)
    Next
    End Sub
    What I need it to do is Loop through All Worksheets and run this code. I tried this:


    Sub ProperCaseworksAlone()
    Dim rng As Range
    Dim ws As Worksheet
    For Each ws In ActiveWorkbook.Worksheets
         With ws
             For Each rng In Range("A2", [a65536].End(xlUp)) 'Start the VBA loop
             rng = StrConv(rng.Text, vbProperCase)
         Next
    Next
    End Sub
    I do not know why it does not work other than thee are two "For Each" Statements? I do not necessarily need Last Row or Used Range. All of Column A can be changed to Proper Case. If the cells are blank, it does no harm.

    I would appreciate any and all advice on what I am doing wrong and how to correct it.

    Thanks so much,

    Kathy

  2. #2
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Your inner (rng) loop is only working on the activesheet since you did not specify ws for A1

    Option Explicit
    
    Sub ProperCaseworksAlone()
        Dim rng As Range
        Dim ws As Worksheet
        Application.ScreenUpdating = False
        For Each ws In ActiveWorkbook.Worksheets
            With ws
                For Each rng In Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp))     ' <<<<<< note the dots on the .Cells to refer to the current ws
                    rng = StrConv(rng.Text, vbProperCase)
                Next
            End With
        Next
        Application.ScreenUpdating = True
    End Sub
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  3. #3
    Moderator VBAX Master georgiboy's Avatar
    Joined
    Mar 2008
    Location
    Kent, England
    Posts
    1,190
    Location
    Do we even need a range loop?
    Sub test()    
        Dim ws As Worksheet
        
        For Each ws In ThisWorkbook.Worksheets
            With ws.UsedRange.Resize(, 1)
                .Value = Application.Proper(.Value)
            End With
        Next ws
    End Sub
    Click here for a guide on how to add code tags
    Click here for a guide on how to mark a thread as solved

    Excel 365, Version 2403, Build 17425.20146

  4. #4
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Quote Originally Posted by georgiboy View Post
    Do we even need a range loop?
    Not really, but I took it a 'teaching opportunity'
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  5. #5
    Moderator VBAX Master georgiboy's Avatar
    Joined
    Mar 2008
    Location
    Kent, England
    Posts
    1,190
    Location
    Quote Originally Posted by Paul_Hossler View Post
    Not really, but I took it a 'teaching opportunity'
    Good point, get lost in the world of "Less is more"
    Click here for a guide on how to add code tags
    Click here for a guide on how to mark a thread as solved

    Excel 365, Version 2403, Build 17425.20146

  6. #6
    VBAX Regular
    Joined
    Mar 2022
    Posts
    20
    Location
    I finally had a chance to try it out. Both options work great and YES thank you so much for the "teaching". I just cannot seem to grasp the loop through each worksheet concept and the changes that need to be made to code when using it.
    Thank you both so much.

  7. #7
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    1. If performance is problem, then .SpecialCells can return just the text cells in column A from the .UsedArea of the ws

    2. For objects, such as the Range 'rng', that do NOT explicitly reference the parent, the current / active 'parent' is implied.

    The .Parent of a .Range is a Worksheet

    So Set rng = Range("A1") [no dot] will use the ActiveSheet, even inside a With / End With

    And Set rng = ws.Range("A1") [dot] will always use Worksheet ws


    If you're looping through worksheets (For Each ws in ...)

    a. without the dot, it will always use the ActiveSheet regardless of the With ws / End With

    b. with the dot, it will always use the explicitly specified Parent, in this case the ws because of the With /End With

    Option Explicit
    
    Sub ProperCaseworksAlone()
        Dim rng As Range
        Dim ws As Worksheet
        Application.ScreenUpdating = False
        For Each ws In ActiveWorkbook.Worksheets
            With ws
                On Error Resume Next    '   in case thee are no text cells
                Set rng = Intersect(.UsedRange, .Columns(1)).SpecialCells(xlCellTypeConstants, xlTextValues)
                rng.Value = Application.Proper(rng.Value)
                On Error GoTo 0
            End With
        Next
       Application.ScreenUpdating = True
    End Sub
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  8. #8
    Knowledge Base Approver VBAX Wizard
    Joined
    Apr 2012
    Posts
    5,642
    I see no performance issues with:

    Sub M_snb()
       For Each it In Sheets
         it.UsedRange.Columns(1) = Application.Proper(it.UsedRange.Columns(1))
       Next
    End Sub

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
  •