Convert column letter to number - excel

I get raw data from querys into Excel, and when preforming VLOOKUP's sometimes I have to count or calculate by hand what column I am going to refer to.
I want a calculator were I type in userform textbox ex: "M", and the other textbox will show the correct column number for "M" (13).
My userform looks like this:
I have come up with something like the code below, I dim every letter as an integer and when that is typed in to the textbox it will add each others values.
I don't know how to code the CommandButton1_click "Räkna".
Private Sub CommandButton1_Click()
'how do i transform letters into numbers here?
End Sub
Sub raknare()
Dim a As Integer
Dim b As Integer
Dim c As Integer
Dim d As Integer
Dim e As Integer
Dim f As Integer
Dim g As Integer
Dim h As Integer
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim l As Integer
Dim m As Integer
Dim n As Integer
Dim o As Integer
Dim p As Integer
Dim q As Integer
Dim r As Integer
Dim s As Integer
Dim t As Integer
Dim u As Integer
Dim v As Integer
Dim w As Integer
Dim x As Integer
Dim y As Integer
Dim z As Integer
Set a = 1
Set b = 2
Set c = 3
Set d = 4
Set e = 5
Set f = 6
Set g = 7
Set h = 8
Set i = 9
Set j = 10
Set k = 11
Set l = 12
Set m = 13
Set n = 14
Set o = 15
Set p = 16
Set q = 17
Set r = 18
Set s = 19
Set t = 20
Set u = 21
Set v = 22
Set w = 23
Set x = 24
Set y = 25
Set z = 26
End Sub

To get info from a dialogue to a variable, you'd do something like
Dim v As Variant
v = Application.InputBox(Prompt:="Letter: ", Title:="Letter", Type:=2)
If CBool(v) Then ' The inputbox returns "false" if cancel is pressed
...
EndIf
If you want to use a userform instead, you'd do something like
Dim s As String
s = UserForm1.TextBox1.Text
To get the column number from its name, you can either do something like what's described in this answer.
Or do what I've done in my office, and do the arithmetic yourself:

I solved my problem! But not the way I initially intended. I took some old code i had from a previous project and made it work on this issue to.
I made a sheet called "DATA" and inserted column A with the alphabet A to CW, and next to that i have the corresponding number for each letter 1-100.
Then i made a search function that looks like this:
Sub rakna()
Dim rSearch As Range
Dim rFound As Range
With Sheets("DATA")
Set rSearch = .Range("A1", .Range("A" & Rows.Count).End(xlUp))
Set rFound = rSearch.Find(What:=TextBox1.Text, LookIn:=xlValues)
If rFound Is Nothing Then
TextBox2.Value = ""
Else
TextBox2.Value = rFound.Offset(0, 1).Value
End If
End With
End Sub
Now I dont need to calculate the columns no more I can just type the one I need in my textbox!

You could try:
Option Explicit
Sub test()
Dim Letter As String
Dim LetterNumber As Long
Letter = "F"
LetterNumber = Range(Letter & 1).Column
End Sub

Related

Excel Macro Goes into Endless Loop

I've been working on this macro and function for a while. The function works fine when I just run it by itself, but when I try to put it into a For loop it repeats forever and never increments. I'll start with the main macro.
Sub Run()
Dim shrt As Worksheet: Set shrt = Worksheets("Shortages")
Dim sTbl As ListObject: Set sTbl = shrt.ListObjects("Shortages_T")
Dim xRng As Range
Dim x As Integer
shrt.Range("H3") = "Can Build"
'x = 9
For x = 9 To 14 Step 1
Set xRng = sTbl.ListColumns(x).DataBodyRange
shrt.Cells(3, x) = BldQty(xRng, x)
Next x
End Sub
If I comment out the loop and manually increment x, it works fine. Once I put it in the loop, it just endlessly repeats and never increments. I've checked with a Print.Debug. The function below is what I'm trying to call with it. I checked the debug and it just keeps running the same range and column over and over again.
Function BldQty(xRng As Range, scol As Integer) As Long
Dim shrt As Worksheet: Set shrt = Worksheets("Shortages")
Dim sTbl As ListObject: Set sTbl = shrt.ListObjects("Shortages_T")
Dim use As Worksheet: Set use = Worksheets("Useage")
Dim uTbl As ListObject: Set uTbl = use.ListObjects("UseTable")
Dim Cell As Range
Dim mdl As String
Dim cRng As Range
Dim qp As Double
Dim div As Double
Dim low As Double
Dim col As Integer
BldQty = xRng(1)
scol = scol - 1
For Each Cell In xRng
If Application.WorksheetFunction.Min(xRng) <= 0 Then
BldQty = 0
Exit For
Else
mdl = Cell.Offset(0, -scol).Value
'VLOOKUP equivalent
qp = uTbl.ListColumns("Component").DataBodyRange.Find(mdl).Offset(0, 1)
div = Cell / qp
If div < BldQty Then
BldQty = div
End If
End If
Next Cell
End Function
Am I calling it wrong in the loop?
ByRef instead of ByVal?
I'm not sure about what your code shall do, but
shrt.Cells(3, x) = BldQty(xRng, x)
goes to
Function BldQty(xRng As Range, scol As Integer) As Long
where scol ist passed by reference
And in this function you change scol so it returns its new value to x
Try
Function BldQty(xRng As Range,ByVal scol As Integer) As Long
ByRef is the default in VBA

How to assign range in a string VBA?

I have a code to highlight words in a cell based on the values in another cells. It works perfectly when I assign FindW = Range("X1") . However the code does not seem to work when I assign range e.g:("X1:X1000") to the string value FindW and I could not find a way to fix this.
Does anyone have any idea?
See the code below:
Dim Rng As Range
Dim FindW As String
Dim xTmp As String
Dim x As Long
Dim m As Long
Dim y As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Übersicht")
Application.ScreenUpdating = False
Application.EnableEvents = False
With ws
FindW = Range("X1:X1000")
y = Len(FindW)
For Each Rng In Range("C:H")
With Rng
m = UBound(Split(Rng.Value, FindW))
If m > 0 Then
xTmp = ""
For x = 0 To m - 1
xTmp = xTmp & Split(Rng.Value, FindW)(x)
.Characters(Start:=Len(xTmp) + 1, Length:=y).Font.ColorIndex = 3
xTmp = xTmp & FindW
Next
End If
End With
Next Rng
End With
End Sub
You can't put the values of a Range of multiple cells directly into a single String variable. However, you can create a String Array and store each cell value individually in the String Array.
The easiest solution is to just use a Variant variable, and put the range values directly in it, like this :
Dim mrange As Range
Dim mVariant As Variant
mVariant = myRange.Value
If you really need your variable to be a String, there are multiples ways to do so:
For example, you can loop through each cell of the Array using something like :
For each mCell in mRange.Cells
mString(i) = mCell.Value
i = i + 1
Next mCell
mRange being your Range, and mString being a String Array. This solution requires for you to know how many cells are in the Range, since the String array needs to be defined with a size.
If you don't know the size of your Range, you can add a step and use a Variant variable.
See here.

How to copy array while removing last character and obtain result as double

I have a table of data in format "numberletter" i.e. 1X, 2.5X, -5X etc. What I am trying to do is to grab the data, remove last character from each cell(there is always only one letter at the end of the value), multiply the result by a constant value and paste it back to a different cells.
Right now, with code below, I am able to get values from first table copied to the second table with last letter removed but the result is string instead of number.
Dim vData
Dim n As Long
Dim r As Long
vData = Range("E6:J500").Value
For n = 1 To UBound(vData, 1)
For r = 1 To 6
If Len(vData(n, r)) <> 0 Then vData(n, r) = Left$(vData(n, r), Len(vData(n, r)) - 1)
Next r
Next n
Range("R6:W500").Value = vData
I've tried to add function below, but I am not able to make it work with my previous code due to mismatch error. Any help would be appreciated.
Function ConvertArray(arrStr() As String) As Double()
Dim strS As String
Dim intL As Integer
Dim intU As Integer
Dim intCounter As Integer
Dim intLen As Integer
Dim arrDbl() As Double
intL = LBound(arrStr)
intU = UBound(arrStr)
ReDim arrDbl(intL To intU)
intCounter = intL
Do While intCounter <= UBound(arrDbl)
arrDbl(intCounter) = CDbl(arrStr(intCounter))
intCounter = intCounter + 1
Loop
ConvertArray = arrDbl
End Function
There may be another better way, but I find .Evaluate an interesting option which in this case could work for you.:
Sub Test()
Dim cnst As Long: cnst = 10
With ThisWorkbook.Sheets("Sheet1") 'Change accordingly
.Range("R6:W500") = .Evaluate("IFERROR(IF(ROW(1:500),LEFT(E6:J500,IF(ROW(1:500),LEN(E6:J500)-1)),"""")*" & cnst & ","""")")
End With
End Sub
Or with a little bit more flexibility with variable ranges:
Sub Test()
Dim rng1 As Range, rng2 as range, cnst As Long
With ThisWorkbook.Sheets("Sheet1") 'Change accordingly
Set rng1 = .Range("E6:J500")
Set rng2 = .Range("R6:W500")
cnst = 10
rng2.Value = .Evaluate("IFERROR(IF(ROW(1:500),LEFT(" & rng1.Address & ",IF(ROW(1:500),LEN(" & rng1.Address & ")-1)),"""")*" & cnst & ","""")")
End With
End Sub
The IFFERROR is in there because you seem to check your range for length above 0 too.
Here you can find why I used ROW(1:500) in .Evaluate:).
The Type Mismatch error is caused because Range.Value returns a variant array not a string array. It is also a 2D Array.
Val() can be used by itself to return the string value as long as the left part of the string contains the value.
Function ConvertArray(arrStr() As Variant, Multiplier As Double) As Double()
Dim results() As Double
ReDim results(1 To UBound(arrStr), 1 To UBound(arrStr, 2))
Dim r As Long, c As Long
For r = 1 To UBound(arrStr)
For c = 1 To UBound(arrStr, 2)
results(r, c) = Val(arrStr(r, c)) * Multiplier
Next
Next
ConvertArray = results
End Function
Sub Test()
Dim data() As Variant
data = Range("E6:J500").Value
Range("R6:W500").Value = ConvertArray(data, 10)
End Sub
Sub Prep()
Range("E6:J500").Formula = "=RandBetween(1,1000)&""X"""
Range("E6:J500").Value = Range("E6:J500").Value
End Sub
You need the VBA Val(String) function. This will take the numerics from your string until it finds a letter. It does a bit more than that as described here.
So you could replace your:
For r = 1 To 6
If Len(vData(n, r)) <> 0 Then vData(n, r) = Left$(vData(n, r), Len(vData(n, r)) - 1)
Next r
With:
For r = 1 To 6
vData(n, r) = Val(vData(n, r)
Next r

scan a cell, with 2 variables ( cells(i,j) )

My string 'strings' does not get any data from the lines where it was supposed to get the data from the cell ( corY, i ).
Here is my code:
Dim strings As String
corY = 2
For i = 5 To 20
strings = ActiveWorkbook.ActiveSheet.Range(Cells(corY, i)).Value
MsgBox (strings)
Next i
The problem is the use of "range" and then "cells". This works for me with a strings in the "B" column of excel.
Sub test5()
Dim strings As String
Dim k As Integer
k = 5
i = 2
corY = 2
For i = 2 To k
strings = ActiveWorkbook.ActiveSheet.Cells(i, corY).Value
MsgBox (strings)
Next i
End Sub
Replace:
strings = ActiveWorkbook.ActiveSheet.Range(Cells(corY, i)).Value
with:
strings = ActiveWorkbook.ActiveSheet.Cells(corY, i).Value
NOTES:
A single Cells() inside Range() does not work. However, here are some examples of setting a range that will work:
Sub examples()
Dim r As Range
Set r = Workbooks("qwerty.xlsm").Worksheets("Junp").Range("A1:B15")
Set r = Worksheets("Junp").Range("A1:B15")
Set r = Range(Cells(1, 1), Cells(15, 2))
Set r = Range("Junp!A1:B15")
End Sub
By using something like the following you get a feedback which range is actually displayed:
Option Explicit
Sub ShowCells()
Dim myString As String
Dim myRange As Range
'Dim iCt As Integer, corY As Integer
Dim iCt As Long, corY As Long
corY = 2
For iCt = 5 To 20
Set myRange = ActiveWorkbook.ActiveSheet.Cells(corY, iCt)
myString = myRange.Value
MsgBox (myRange.Address & ":" & myString)
Next iCt
End Sub

Excel VBA For each nested loop

I am trying to build an Excel workbook that takes data from one sheet, and fills out another based on a system name. I am having a problem with the first for next loop. It works for the first system, but if there are more than one item in the system it just stops working. The second for each loop works great. Is there a better way to run my first loop. I try an if the first For each variable matches the second for each then increment, but the code says the next Inspectcell does not have a for each. The system name is always in column C and starts at C7
Sub fillthereport()
Dim xx As Variant, ws As Variant, yy As Variant
Dim ws2 As Variant, xxx As Variant, yyy As Variant
Dim rowed As Integer, b As Integer
'Dim MySht As Worksheet
Dim MyPic As Shape
Dim MyLeft As Single, MyTop As Single
Dim conv As Variant
Dim item As Variant
Dim picnum As Variant
Dim mergecells As String, mergecells2 As String, mergecolor As String
Dim horstart As Variant, horend As Variant
Dim verstart As Variant, verend As Variant
Dim Inspectcell As Range, reportcell As Range
'worksheets loop operator
ws = 1
'worksheets loop operator to
ws2 = 6
'row designator from
xx = 7
'column designator from
yy = 3
'row designator to
xxx = 68
'column designator to
yyy = 37
'This is not the variable you are looking for
b = 0
'These are the variables you are looking for
yel = 0
bl = 0
re = 0
Folderpath = Application.ActiveWorkbook.Path
Application.ScreenUpdating = False
reportcell = Worksheets("inspection Data").Range("C7")
'make extra sheets in the report to be filled
For Each Inspectcell In Worksheets("inspection Data").Range("C7:C18")
If Inspectcell = reportcell Then
Worksheets(ws2).Select
Worksheets(ws2).Range("A60:AY114").Select
Selection.Copy
Sheets(ws2).Range("A115:AY169").Select
ActiveSheet.Paste
Sheets(ws2).Range("A170:AY224").Select
ActiveSheet.Paste
'reportcell = Inspectcell
For Each reportcell In Worksheets("inspection Data").Range("C7:C18")
If reportcell = Inspectcell Then
'(This is about 110 lines of code that work great)
xx = xx + 1
b = b + 1
'worksheets loop operator
'ws = ws + 1
'worksheets loop operator to
'ws2 = ws2 + 1
'column designator from
'yy = yy + 1
'row designator to
If Not b Mod 3 = 0 Then
xxx = xxx + 16
Else
xxx = xxx + 23
End If
Else 'If xx = 15 Then
Exit For
End If
'xxx = xxx + 22
Next reportcell
ws2 = ws2 + 1
'Else
'Exit for
End if
Next Inspectcell

Resources