Excel VBA基于输入值查找下一列
在我正在编写的一个程序中,我取两列数字并对它们进行计算。我不知道这两列位于何处,直到用户告诉我(他们在工作簿中我的代码所在的单元格中输入列值) 例如,如果用户输入“A”和“B”作为所有信息所在的列,我可以基于这些值执行计算。同样,如果他们想分析另一个工作表(或工作簿),并且列在“F”和“G”中,他们可以输入这些。问题是,我要求用户输入这两列以及其他四列(最后四列是结果列)。我这样做的目的是希望我能够使它变得灵活,但现在不灵活是可以接受的 我的问题是,如果给我一个信息的位置值(比如说“F”),我怎么才能知道输入值之后或之前的列是什么。因此,如果只给我“F”,我就可以创建一个变量来保存“G”列 下面是在我需要解决这个新问题之前变量如何工作的示例:Excel VBA基于输入值查找下一列,excel,vba,Excel,Vba,在我正在编写的一个程序中,我取两列数字并对它们进行计算。我不知道这两列位于何处,直到用户告诉我(他们在工作簿中我的代码所在的单元格中输入列值) 例如,如果用户输入“A”和“B”作为所有信息所在的列,我可以基于这些值执行计算。同样,如果他们想分析另一个工作表(或工作簿),并且列在“F”和“G”中,他们可以输入这些。问题是,我要求用户输入这两列以及其他四列(最后四列是结果列)。我这样做的目的是希望我能够使它变得灵活,但现在不灵活是可以接受的 我的问题是,如果给我一个信息的位置值(比如说“F”),我怎
Dim first_Column As String
Dim second_Column As String
Dim third_Column As String
first_Column = Range("B2").Text
second_Column = Range("B3").Text
third_Column = Range("B4").Text
这里的单元格B2-B4是用户输入值的位置。一般来说,我希望能够不再有B3和B4了。我觉得偏移量(0,1)可能会有所帮助,但到目前为止,我无法正确地实现它
谢谢,
Jesse Smotheron使用VBA中的Asc()和Chr()函数,如下所示:
Dim first_Column As String
Dim second_Column As String
first_Column = Range("B2").Text
second_Column = Chr(Asc(first_Column) + 1)
Asc(s)
函数返回字符串“s”的第一个字符的ASCII码(整数,通常介于0和255之间)
Chr(
c)
函数返回一个字符串,该字符串包含与给定代码“c”对应的字符
大写字母(A到Z)是ASCII码65到90。只需谷歌ASCII查询更多细节
注:只要第一列在“A”和“Y”之间,上述代码就可以了;对于列“AA”等,这将需要更多的工作,但Asc()和Chr()仍然是为此编码的条件。您使用偏移量的方法是正确的。下面是一个测试函数,它展示了两种不同的方法:
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
更新:重新阅读您的问题后,我意识到您试图根据用户输入的列字母进行偏移@rskar的答案将改变列字母,但在代码中使用列编号会容易得多。例如:
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
这里有两个函数可以帮助您处理列>“Z”。它们将列的文本形式转换为列索引(作为长值),反之亦然:
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
例如,现在您的问题可以很容易地解决
newColumn = ColIntToText(ColTextToInt(oldColumn)+1)
根据mwolfe02的备注进行编辑:
当然,如果您对列名不感兴趣,而只想在用户给定的列的正下方获取给定行中特定单元格的range对象,那么这段代码就是“过度杀戮”。在这种情况下,一个简单的
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
我会的。根据其他人的评论(他们都提出了有效的观点),这里有一个更好的解决方案,使用
偏移量
和地址
:
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)
上述内容适用于任何有效的列名,包括“Z”和“AA”等。关于@rskar的答案,存在一些语法问题。但是,它有助于生成一个函数,该函数根据输入列“字母”和向右的所需偏移量获取列“字母”:
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
我没听说过那些。。。。。通过查看代码,我不太确定代码在做什么,很抱歉,我对VBAOk还是很陌生,我刚刚编写了second_Column=Chr(Asc(first_Column))。如果第一列为“A”,则此行使第二列也为“A”,同样,如果第一列为“F”,则第二列也为“F”。我试着快速地修改它,并将其更改为second_Column=Chr(Asc(first_Column+1)),但类型不匹配。由于我不知道用户将输入什么,有没有办法获得Asc返回的号码?。。。。代码中Asc和Chr前面的问号是什么?代码告诉您,
newcolumn=Chr(Asc(oldcolumn)+1)
将为您提供所需内容,只要oldcolumn在“A”到“Y”之间。不幸的是,这不适用于“Z”、“AA”、“AB”等列,以及?是Debug.Print的快捷方式。@Jesse-只需重写答案。欢迎使用VBA编程!对不起,关于问号的事情,我以为你已经知道了即时窗口。希望这能帮助你开始。我是不是遗漏了什么?提问者是否试图做一些无法直接使用.Offset()
处理的事情?@mwolfe02:他问的是当他知道“F”时如何到达“G”。如果他知道“AF”的话,也可以是“AG”。也许一个简单的“偏移量”就足以到达正确的单元格或列范围,但这不会给出文本列名。但我同意你的看法,他应该先用“偏移”来解决他的问题。好的。。。。你显然比我更擅长编码,哈哈。我必须承认我很难理解代码。我不确定您是否愿意花时间尝试向我解释,我从来都不擅长通过查看代码来实现递归。谢谢你的帮助我想我对函数到底是什么混淆了我的想法。我更习惯C#或Java。我假设行“ColTextToInt=Asc(col)-Asc(“A”)+1”是在再次调用函数。但现在我知道这不是递归的,我想我能弄明白。谢谢在VBA中,函数“MyFunction”中的行“MyFunction=value”与“return value”的意思相同;在C#中,这看起来确实与我在使用Offset时尝试创建的有点不同。这里的情况是,我现在只有一个用户可以输入值的单元格。假设用户输入的单元格为“B2”b