Let's say I have this string which represents a cell: A2.
What should I do to covert it to coordinates: (2, 1) ?
Without VBA
Suppose, cell C2 contains string "A2".
Then
=INDIRECT(C2) returns reference to A2
=ROW(INDIRECT(C2)) returns row number - 2
=COLUMN(INDIRECT(C2)) returns column number - 1
="(" & ROW(INDIRECT(C2)) & "; " & COLUMN(INDIRECT(C2)) & ")" returns coordinates in format (x; y) - (2; 1)
UPD:
If you're using UDF, change your parameter type from String to Range:
Function GetData(Cell As Range)
MsgBox "My row is " & Cell.Row
MsgBox "My column is " & Cell.Column
End Function
if you call this UDF from worksheet like this: =GetData(A2), msg box would pop-up:
"My row is 2"
"My column is 1"
You can use Column and Row properties of the Range object:
Range("A2").Row
Range("A2").Column
Examlpe:
Sub test()
Dim x As String
x = "A2"
MsgBox GetRow(x) & " " & GetColumn(x)
End Sub
Function GetRow(Cell As String)
GetRow = Range(Cell).Row
End Function
Function GetColumn(Cell As String)
GetColumn = Range(Cell).Column
End Function
Related
I have a userform in which user can fill the data and data will insert in column C to Z. I need a code, either in worksheet or in userform to auto fill serial number starting with BA00860 which will fill in column A everytime data has enter.
I tried with the below Code under the Commandbutton_Click I was able to generate Serial numbers from BA00860 to BA00869, then after it is starting with BA01861 but not BA00870. Please correct my code as I required to be BA00860 … BA00870 … BA00880 and so on.
Me.txtId.Value = "BA" & Format(Application.Max(Sheets("Tasks").Range("A12:A65536")) + 1, "00860")
ActiveCell.Offset(0, 0).Value = Me.txtId.Value
ActiveCell.Offset(0, 0).NumberFormat = "00860"
Note that this .NumberFormat = "00860" is no valid number format.
You can do this easily with a formula. Assume your first serial number is written in A1 like …
Then you can just use the formula =LEFT(A1,2) & TEXT(RIGHT(A1,5)+1,"00000") in cell A2 and copy it down to get the following:
In VBA you could use something like
Dim LastSN As String
LastSN = Range("A1").Value 'eg BA00860
Dim NextSN As String
NextSN = Left$(LastSN, 2) & Format$(Right(LastSN, 5) + 1, "00000")
Full example according comments:
Sub Test()
Dim LastSN As String
LastSN = "BA00860"
Dim NextSN As String
NextSN = Left$(LastSN, 2) & Format$(Right(LastSN, 5) + 1, "00000")
MsgBox "LastSN was: " & LastSN & vbCrLf & "NextSN is: " & NextSN
End Sub
I have below text in Excel cell:
$abcd.$efghijk.$lmn.$op.$qrst.
I want above text in following format in Excel cell using Excel formula only:
abcd$abcd.efghijk$efghijk.lmn$lmn.op$op.qrst$qrst.
Here's what I will suggest based on discussion.
In a general module, insert following code.
Public Function RepeatCustom(strInput As String) As String
Dim varInput As Variant
Dim i As Long
If Len(strInput) = 0 Then
RepeatCustom = ""
Else
varInput = Split(strInput, ".")
For i = LBound(varInput) To UBound(varInput)
RepeatCustom = RepeatCustom & " " & Mid(varInput(i), 2, Len(varInput(i))) & varInput(i)
Next
RepeatCustom = Replace(Trim(RepeatCustom), " ", ".") & "."
End If
End Function
And then assuming cell containing original data is A2, you can use above UDF:
=RepeatCustom(A2)
Just note that the code is minimum and is based on sample posted.
I'm attempting to create a form for data entry of lab results, which validates an answer based on the specification of the product tested. The user enters the following information: Product Code and SG result etc
My source data is a table with 4 columns,
Product Code, Description, SG low, SG high
SOURCE
When the user enters the Product Code and SG in the form I would like it to validate based on the specific range allowed for that product (from the source data), and have a dialogue box asking the user to reconsider the result entered (if it were outside of the range).
Easy enough to flag with conditional formatting in the results sheet, but I don't want my users to have access to it.
RESULTS
I need to refer to separate Range VLOOKUP to return the specs.
THE FORM
Thanks in advance!
(update)
Private Sub CommandButton1_Click()
Dim i As Integer
i = 2
While ThisWorkbook.Worksheets("Sheet2").Range("A" & i).Value <> ""
i = i + 1
Wend
Dim losg, loph, hisg, hiph As Double
losg = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 3, False)
hisg = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 4, False)
loph = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 5, False)
hiph = Application.WorksheetFunction.VLookup(ProdCode.Text, Sheet1.Range("A1:F24"), 6, False)
If SGresult.Text < losg Then
MsgBox "SG result " & SGresult.Text & " too low"
ElseIf SGresult.Text > hisg Then
MsgBox "SG result " & SGresult.Text & " too high"
Else: MsgBox "SG result " & SGresult.Text & " just right"
End If
If pHresult.Text < loph Then
MsgBox "ph result " & pHresult.Text & " too low"
ElseIf pHresult.Text > hiph Then
MsgBox "ph result " & pHresult.Text & " too high"
Else: MsgBox "ph result " & phresult.Text & " just right"
End If
ThisWorkbook.Worksheets("Sheet2").Range("A" & i).Value = ProdCode.Value 'Enter Code in Column A
ThisWorkbook.Worksheets("Sheet2").Range("C" & i).Value = BNenter.Value 'Enter BN in Column C
ThisWorkbook.Worksheets("Sheet2").Range("D" & i).Value = DOMenter.Value 'Enter DOM in Column D
ThisWorkbook.Worksheets("Sheet2").Range("E" & i).Value = SGresult.Value 'Enter SG result in Column E
ThisWorkbook.Worksheets("Sheet2").Range("F" & i).Value = pHresult.Value 'Enter pH result in Column F
ThisWorkbook.Worksheets("Sheet2").Range("K" & i).Value = BatcherID.Value 'Enter Batcher ID in Column K
End Sub
Save Products in column "K" and valid result for respective product in column "L". Below code will give you desired output
Dim result, prod As String
Dim rng As Range
result = Val(resultText.Value)
prod = prodText.Value
ActiveSheet.Activate
On Error GoTo step:
Set rng = Range("K:K").Find(What:=prod, LookIn:=xlValues, LookAt:=xlWhole)
If rng.Offset(0, 1).Value <> result Then
MsgBox "The result entered is out of valid range!"
End If
Exit Sub
step:
MsgBox "Invalid Product"
Exit Sub
edited after OP clarified the "form" was a "UserFom"
You may want to check user input while he/she's editing/exiting any control instead of waiting for the CommandButton1_Click event and check them all together
Such a "modular" approach should keep code more easy to control and maintain
For example the TextBox Exit event could be used to check the user input as he/she's leaving it and have him/her come back to it in case of wrong input
Moreover
since "Product Code" must be chosen between those listed in "Source" worksheet column "A"
you may want to use a ComboBox control and have the user choose one out of a list
since "Product Name" must be the one corresponding to the chosen "Product Code"
you may want to use a Label control and have the user simply looks at what name corresponds to the product code he just chose
Following what above and assuming "ProductNameLbl" as the label name, your userform code could be something like follows:
Option Explicit
Private Sub UserForm_Initialize()
Me.ProdCodeCB.List = GetSourceData(1) '<--| fill Product Name combobox list with "Source" worksheet column 1 data
End Sub
Private Sub ProdCodeCB_Change() '<--| fires when the user change the combobox selection
Me.ProdNameLbl.Caption = Worksheets("Source").Cells(Me.ProdCodeCB.ListIndex + 2, 2) '<--| update Product Name label with the name corresponding to the chosen Product Code
End Sub
Private Sub SGresultTB_Exit(ByVal Cancel As MSForms.ReturnBoolean) '<--| fires upon exiting the SGresult textbox
Dim msgErr As String
With Me '<--| reference the Userform
If .ProdCodeCB.ListIndex <> -1 Then '<--| if a valid selection has been made in 'ProductCode' combobox
If Not IsValueInRange(.SGresultTB, GetProdCodeRange(.ProdCodeCB.ListIndex + 1), msgErr) Then '<-- if value out of range then...
With .SGresultTB
MsgBox "SG value " & .Value & msgErr _
& vbCrLf & vbCrLf & "Please reconsider the value you input in 'SG' texbox"
Cancel = True
.SetFocus '<--| get the user back to the textbox
' following two lines select the textbox text so that the user can delete it
.SelStart = 0
.SelLength = Len(.Text)
End With
End If
End If
End With
End Sub
'-------------------------------------------------
' helper functions
'---------------------------
Function GetSourceData(colIndex As Long)
' this function returns an array with "Source" worksheets data in passed column from its row 2 to last not empty one
With Worksheets("Source") '<--| reference "Source" worksheet
GetSourceData = Application.Transpose(.Range(.Cells(2, colIndex), .Cells(.Rows.Count, colIndex).End(xlUp)).Value)
End With
End Function
Function IsValueInRange(tb As MSForms.TextBox, rangeArr As Variant, msgErr As String) As Boolean
' this function returns a boolean (true/false) with the result of the checking whether the passed texbox (tb) text exceeds the passed range (rangeArr)
' msgErr is also set to some text if the range is exceeded
With tb
Select Case CDbl(.Value) '<-- prepare to act accordingly to its value
Case Is < rangeArr(1) '<--| if it's smaller than "SG Low" value
msgErr = " is lower than 'SG Low' = " & rangeArr(1) '<-- build the final part of the error message correspondingly
Case Is > rangeArr(2) '<--| while if it's greater than "SG High" value
msgErr = " is greater than 'SG High' = " & rangeArr(2) '<-- build the final part of the error message correspondingly
End Select
End With
IsValueInRange = msgErr = ""
End Function
Function GetProdCodeRange(iProd As Long)
' this function returns an array of the SG minimum and maximum values in "Source" worksheet corresponding to the chosen product
With Worksheets("Source") '<--| reference "Source" worksheet
With .Range("A2", .Cells(.Rows.Count, "A").End(xlUp)) '<--| reference its column "A" cels from row 2 down to last not empty one
GetProdCodeRange = Application.Transpose(Application.Transpose(.Cells(iProd, 1).Offset(, 2).Resize(, 2).Value)) '<--| return an array with "SG low" and "SG high" values corresponding to the product index passed
End With
End With
End Function
'-------------------------------------------------
as you may see, I named controls after the names you chose for them except for adding a suffix to tell what kind of control they are:
ProdCodeCB: "CB" -> it's a ComboBox control name
SGresultTB: "TB" -> it's a TextBox control name
ProdNameLbl: "Lbl" -> it's a Label control name
I have been reading in different websites how to create a function that gets a string as argument which is the name of a column in excel(The name of the column is defined by the value found in row 4;name, status, phone,etc) and returns two values; The column letter(A,B,C,D,etc.) AND the column title(name, status, phone). So far I have this function that returns the letter of the column where the title is found but I am not sure how to modify this function so it returns the column letter AND the column title as well. The argument for this function is the column title which is retrieved from an array. Probably I cannot use one argument and get two values, no sure. I would appreciate any help. Thank you
Function ColumnLetters(r As Range) As String
Dim i As String
i = r.Address(False, False)
ColumnLetters = Left(i, Len(i) - Len(Format(r.row, "0")))
End Function
Sub Tester()
Dim a
a = ColumnInfo(Range("D10"))
msgbox "Column: " & a(0) & " Header: " & a(1)
End sub
Function ColumnInfo(r As Range)
Set r = r.Cells(1)EntireColumn
ColumnInfo = Array(Replace(r.Cells(1).Address(False, False), "1", ""), _
r.Cells(4).Value)
End Function
I am fairly new to Excel Macros and I am looking for a way to loop through the row headings and columns headings and combine them into one cell for each row and column heading until I have combined all of them.
An example of the First Column cell would be "Your Organizations Title"
An Example of the First Row Cell Would be "22. Cheif Investment Officer"
An example of the first combined cell that I want on a new sheet would be this: "22. Chief Investment Officer (Your Organization's Title)
I then want the combined cells on the new sheet to offset one column to the right until it has iterated through all of the rows and columns.
I have just joined the forum and it will not let me post images or I would have. Perhaps this gives a better idea, here is my code now:
Sub Fill()
' Select cell A2, *first line of data*.
Set title = Sheets("Compensation, 3").Range("B6:B500")
Set descr = Sheets("Compensation, 3").Range("C5:AAA5")
' Set Do loop to stop when an empty cell is reached.
Do Until IsEmpty(title.Value)
Do Until IsEmpty(descr.Value)
ActiveCell.Offset(0, 1).Formula = _
"=title.value & "" ("" & descr.value & "")"""
Set descr = descr.Offset(0, 1)
Loop
Set title = title.Offset(1, 0)
Loop
End Sub
When I run it goes puts this into the active cell:
=title.value & " (" & descr.value & ")"
It does not recognize the variables and come up with the NAME error. It also goes into an infinite loop with no output besides the one cell.
Edit:
I cannot answer my own question because I am new to the forum, but using a combination of your answers I have solved the problem!
Here is the finished code:
Sub Fill()
' Select cell A2, *first line of data*.
Set title = Sheets("Compensation, 3").Range("B6")
Set descr = Sheets("Compensation, 3").Range("C5")
offsetCtr = 0
' Set Do loop to stop when an empty cell is reached.
Do Until IsEmpty(title.Value)
Do Until IsEmpty(descr.Value)
ActiveCell.Offset(0, offsetCtr).Formula = title.Value & " (" & descr.Value & ")"
offsetCtr = offsetCtr + 1
Set descr = descr.Offset(0, 1)
Loop
Set descr = Sheets("Compensation, 3").Range("C5")
Set title = title.Offset(1, 0)
Loop
End Sub
Thank you so much!
Option Explicit
Sub GenerateAndPasteFormulaForTitleAndDescription( _
ByVal titlesRange As Range, ByVal descriptionRange As Range, _
ByVal startCellOnDestination As Range)
Dim title As Range
Dim descr As Range
Dim offsetCtr As Long
Dim formulaTemplate As String
Dim newFormula As String
formulaTemplate = "=CONCATENATE([1], '(', [2], ')')"
startCellOnDestination.Worksheet.EnableCalculation = False
For Each title In titlesRange.Cells
For Each descr In descriptionRange.Cells
If title.Value <> "" And descr.Value <> "" Then
newFormula = Replace(formulaTemplate, "[1]", _
title.Address(External:=True))
newFormula = Replace(newFormula, "[2]", _
descr.Address(External:=True))
newFormula = Replace(newFormula, "'", Chr(34))
startCellOnDestination.Offset(0, offsetCtr).Formula = newFormula
offsetCtr = offsetCtr + 1
End If
Next
Next
startCellOnDestination.Worksheet.EnableCalculation = True
End Sub
Here is how to call the above procedure
GenerateAndPasteFormulaForTitleAndDescription _
Sheets("Compensation, 3").Range("B6:B500"), _
Sheets("Compensation, 3").Range("C5:AAA5"), _
Sheets("new sheet").Range("B5")
EDIT: The code loops through combination of title and description, checks if both of them aren't empty and creates a formula. It pastes the formula into the start cell (Sheets("new sheet").Range("B5") in this case) and moved ahead and pastes the next formula in the column next to it
Basically, you are trying to use VBA objects in worksheet functions. It doesn't quite work that way.
Try replacing
"=title.value & "" ("" & descr.value & "")"""
with
=title.value & " (" & descr.value & ")"