VBA Finding the next column based on an input value

后端 未结 5 1421
隐瞒了意图╮
隐瞒了意图╮ 2021-01-27 21:56

In a program that I\'m trying to write now I take two columns of numbers and perform calculations on them. I don\'t know where these two columns are located until the user tell

相关标签:
5条回答
  • 2021-01-27 22:17

    Make use of the Asc() and Chr() functions in VBA, like so:

    Dim first_Column As String
    Dim second_Column As String
    
    first_Column = Range("B2").Text
    second_Column = Chr(Asc(first_Column) + 1)
    

    The Asc(s) function returns the ASCII code (in integer, usually between 0 and 255) of the first character of a string "s".

    The Chr(c) function returns a string containing the character which corresponds to the given code "c".

    Upper case letters (A thru Z) are ASCII codes 65 thru 90. Just google ASCII for more detail.

    NOTE: The above code will be fine so long as the first_Column is between "A" and "Y"; for columns "AA" etc., it will take a little more work, but Asc() and Chr() will still be the ticket to coding for that.

    0 讨论(0)
  • 2021-01-27 22:23

    You were on the right track with Offset. Here is a test function that shows a couple different approaches to take with it:

    Sub test()
    
    Dim first_Column As String
    Dim second_Column As String
    Dim third_Column As String
    Dim r As Range
    
        first_Column = Range("B2").Text
        second_Column = Range("B2").Offset(1, 0).Text
        third_Column = Range("B2").Offset(2, 0).Text
        Debug.Print first_Column, second_Column, third_Column
    
        Set r = Range("B2")
        first_Column = r.Text
        Set r = r.Offset(1, 0)
        second_Column = r.Text
        Set r = r.Offset(1, 0)
        third_Column = r.Text
        Debug.Print first_Column, second_Column, third_Column
    
    End Sub
    

    UPDATE: After re-reading your question I realize you were trying to do offsets based on a user-entered column letter. @rskar's answer will shift the column letter, but it will be a lot easier to work with the column number in code. For example:

    Sub test()
    Dim first_Col As Integer, second_Col As Integer
        first_Col = Cells(, Range("B2").Text).Column
        second_Col = first_Col + 1
    
        Cells.Columns(first_Col).Font.Bold = True
        Cells.Columns(second_Col).Font.Italic = True
    End Sub
    
    0 讨论(0)
  • 2021-01-27 22:29

    There are a few syntactical problems with @rskar's answer. However, it was helpful in producing a function that grabs a column "letter", based on an input column "letter" and a desired offset to the right:

    Public Function GetNextCol(TheCol As String, OffsetRight As Integer) As String
        Dim TempCol1 As String
        Dim TempCol2 As String
        TempCol1 = Range(TheCol & "1").Address
        TempCol2 = Range(TempCol1).Offset(0, OffsetRight).Address(0, 0, xlA1)
        GetNextCol = Left(TempCol2, Len(TempCol2) - 1)
    End Function
    
    0 讨论(0)
  • 2021-01-27 22:29

    In light of the comments of others (and they all raised valid points), here is a much better solution to the problem, using Offset and Address:

    Dim first_Column As String
    Dim second_Column As String
    Dim p As Integer
    
    first_Column = Range("B2").Text
    
    second_Column = _
        Range(first_Column + ":" + first_Column).Offset(0, 1).Address(0, 0, xlA1)
    p = InStr(second_Column, ":")
    second_Column = Left(second_Column, p - 1)
    

    The above should work for any valid column name, "Z" and "AA" etc. included.

    0 讨论(0)
  • 2021-01-27 22:34

    Here are two functions that will help you dealing with columns > "Z". They convert the textual form of a column to a column index (as a Long value) and vice versa:

    Function ColTextToInt(ByVal col As String) As Long
        Dim c1 As String, c2 As String
        col = UCase(col) 'Make sure we are dealing with "A", not with "a"
        If Len(col) = 1 Then  'if "A" to "Z" is given, there is just one letter to decode
            ColTextToInt = Asc(col) - Asc("A") + 1
        ElseIf Len(col) = 2 Then
            c1 = Left(col, 1)  ' two letter columns: split to left and right letter
            c2 = Right(col, 1)
            ' calculate the column indexes from both letters  
            ColTextToInt = (Asc(c1) - Asc("A") + 1) * 26 + (Asc(c2) - Asc("A") + 1)
        Else
            ColTextToInt = 0
        End If
    End Function
    
    Function ColIntToText(ByVal col As Long) As String
        Dim i1 As Long, i2 As Long
        i1 = (col - 1) \ 26   ' col - 1 =i1*26+i2 : this calculates i1 and i2 from col 
        i2 = (col - 1) Mod 26
        ColIntToText = Chr(Asc("A") + i2)  ' if i1 is 0, this is the column from "A" to "Z"
        If i1 > 0 Then 'in this case, i1 represents the first letter of the two-letter columns
            ColIntToText = Chr(Asc("A") + i1 - 1) & ColIntToText ' add the first letter to the result
        End If
    End Function
    

    Now your problem can be solved easily, for example

    newColumn = ColIntToText(ColTextToInt(oldColumn)+1)
    

    EDITED accordingly to the remark of mwolfe02:

    Of course, if you are not interested in the column names, but just want to get a range object of a specific cell in a given row right beneath a column given by the user, this code is "overkill". In this case, a simple

     Dim r as Range
     Dim row as long, oldColumn as String
     ' ... init row and oldColumn here ...
    
     Set r = mysheet.Range(oldColumn & row).Offset(0,1)
     ' now use r to manipulate the cell right to the original cell
    

    will do it.

    0 讨论(0)
提交回复
热议问题