Cell reference based on FOR loop index - excel

Here is some of my code:
Dim wbX As Workbook
Dim wbY As Workbook
Set wbX = Application.Workbooks.Open("C:\Converter\aaa.xls")
Set wbY = Application.Workbooks.Open("C:\Converter\bbb.xlsx")
For i = 1 To wbX.Sheets.Count
wbY.Sheets(1).Activate
Range("Y" & i + 2).Select
ActiveSheet.Range("Y" & i + 2).Formula = "=RIGHT(("S" & i + 2); 4)"
The problem is that ("S" & i + 2) is not recognized as a cell - VBA spits out syntax errors.

Your expression "Y" & i + 2 does not yield a valid cell reference because you concatenate a number to a string. You must convert the numeric expression to a string:
"Y" & Str(i + 2)
What I understand from your comment, the assignment should be written as:
"=LEFT(S" & Trim(Str(i + 2)) & "; 4)" ' yields e.g.: =LEFT(S3; 4)
(The LEFT function gets the first characters from a string. This assumes the cells you reference contains strings, or that VB converts the value to a string first. And here you must use Trim(Str(i + 2)) because you are constructing a string to place as a formula in the cell.)

Maybe this example helps you:
Option Explicit
Sub test()
Dim rngC As Range
For Each rngC In Range("C2:C100")
rngC.Offset(0, 4) = Right(rngC, 4)
Next
End Sub

Related

.Value does not read whole string

In my macro I need to read a value out of a Cell. The values always start with an ' followed by a number like '1 or '1001.
When I attempt to read the cell like s = wsout.Cells(headerVal(6, 1) + i, 1).Value, I only get 1 instead of '1.
wsout is a worksheet and s is defined as a String.
How do I read the actual contents of the cell?
You need the Range.PrefixCharacter Property whih returns the prefix character for the cell.
Here is an example
s = wsout.Cells(headerVal(6, 1) + i, 1).PrefixCharacter & _
wsout.Cells(headerVal(6, 1) + i, 1).Value
Debug.Print s
If the cell has '1 then s above will have '1

VBA code to auto serial number in column A when data entered in the userform

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

Adding freshly created formula into new module

I've just created a brand new macro. Took function down below from internet (all credits goes to trumpexcel.com), code down below
Function CONCATENATEMULTIPLE(Ref As Range, Separator As String) As String
Dim Cell As Range
Dim Result As String
For Each Cell In Ref
Result = Result & Cell.Value & Separator
Next Cell
CONCATENATEMULTIPLE = Left(Result, Len(Result) - 1)
End Function
Then I proceed to extract data from various columns and into the one (my table is 20 rows x 10 columns)
Sub conact_data()
Dim i As Integer
For i = 2 To Cells(Rows.Count, "A").End(xlUp).Row
Cells(i, "M").Value = Cells(i, "A").Value & " " & _
Cells(i, "B").Value & " / " & Cells(i, "D").Value & "; "
Next i
End Sub
Thanks to that I've got combined data from column A, B and D, so its 20 rows. All I want to do now is to concatenate data from M2:M21 using CONCATENATEMULTIPLE function therefore I try various approach (I want this huge line in P2 cell) like :
Cells(2, 16).Value = CONCATENATEMULTIPLE (M2:M21, " ")
or
Range("P2") = "CONCATENATEMULTIPLE (M2:M21, " ")"
I don't really know how to apply that
Secondly, I'd like withdraw the Cells(i, "B").Value as percentage. Can I do that in one line like Cells(i, "B").NumberFormat="0.00%".Value (which is not working for me obviously) else I need to copy column B into another column with number format and then combine the new column, properly formatted instead of column B?
Thanks in advance
Percent format: Range("B" & i).NumberFormat = "0.00%"
CONCATENATEMULTIPLE
In VBA, CHR(32) = " "
In Excel, CHAR(32) = " "
With that being said...
'Value
Range("P2").Value = CONCATENATEMULTIPLE(Range("M2:M21"), CHR(32))
'Formula
Range("P2").Formula = "=CONCATENATEMULTIPLE(M2:M21, CHAR(32))"
You should really qualify all of your ranges with a worksheet
Say your workbook has 10 sheets. When you say Range("P2"), how do we (VBE) know what sheet you mean? Objects need to be properly qualified. Sometimes this is not a huge issue, but when you are working across multiple sheets, not qualifying ranges can lead to some unexpected results.
You can qualify with a worksheet a few ways.
Directly: ThisWorkbook.Sheets("Sheet1").Range("P2").Copy
Or use a variable like so
Dim ws as Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
ws.Range("P2").Copy
Now there is no room for ambiguity (potential errors) as to the exact location of Range("P2")
First of all, remove your ConcatenateMultiple() code, and instead use Excel worksheet function CONCAT(), which takes a range and a delimiter as parameters.
Here is how you can handle the percentage issue and supply a default for non-numeric items. I've also cleaned up the way you reference your data range.
Sub concat_data()
Dim rngRow As Range, vResult As Variant
Const DEFAULT = 0 'Can also be set to a text value, eg. "Missing"
For Each rngRow In [A2].CurrentRegion.Rows
If IsNumeric(rngRow.Cells(, 4)) Then vResult = rngRow.Cells(, 4) * 100 & "%" Else vResult = DEFAULT
Range("M" & rngRow.Row) = rngRow.Cells(, 1) & rngRow.Cells(, 2) & "/" & vResult & ";"
Next
[M2].End(xlDown).Offset(1).Formula = "=CONCAT(M2:M" & [M2].End(xlDown).Row & ",TRUE,"" "")"
End Sub
I'm not a fan of hard-coding range references, like the [A2] or Range("M"), but will leave that for another time.

Excel VBA Index/Lookup

Dim worksheet1 As Worksheet
Set worksheet1 = ActiveSheet
Dim workbook2 As Workbook
Set workbook2 = Workbooks.Open(("F:\Project Sweep\Kim Checklist\" & worksheet1.Cells(19, 12) & "\Consumers.xlsx"))
Dim targetString As String
targetString = "index('" & workbook2.Path & "\[" & workbook2.Name & "]Time'!$A$1:$E$366, 1, 1)"
Dim i As Long
For i = 0 To 4
worksheet1.Cells(7 + (i * 2), 7) = Application.Calculate(targetString)
Next i
The code is attempting to do the following:
From worksheet 1, where the function is supposed to be called, it is supposed to pull from the worksheet Time in workbook 2, the value located at cell A1 (to be updated later to be iterative when the code is working), and place it in cell(7,7), cell(9, 7), cell(11, 7) and so on.
The above code is giving the error "Compile Error: wrong number of arguments or invalid property assignment"
The other option I was using was
worksheet1.Range(Cells(7 + (i * 2), 7)).Formula = "=" & targetString
literally just placing the formula in the cell. But that gives the error "Run time error 1004: method range of object failed"
Any help would be appreciated thank you in advance for your time.
You're looking for Application.Evaluate, not Application.Calculate.
For i = 0 To 4
worksheet1.Cells(7 + (i * 2), 7) = Application.Evaluate(targetString)
Next i
I'm a little unclear on what is going to change during that loop since the string that looks like a formula is static throughout.
Use .Address with External:=True to resolve a complete external path, workbook, worksheet and range.
with workbook2.worksheets("Time").range("A1:E366")
targetString = "index(" & .address(external:=true) & ", 1, 1)"
debug.print targetString
end with

Excel VBA code mid function

I have the following string "123 - 456789". What I am trying to do is find a way to only capture the remaining characters after the second space - "456789" - regardless the length of the string.
I have the follow set of code:
For leftLoop = 2 To leftNumberOfCells
Range("A" & iRow) = Split(Range("B" & iRow).Value, " ")
Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)
iRow = iRow + 1
Next leftLoop
The code line "Range("B" & iRow) = Mid("B" & iRow, InStr("B" & iRow, " "), 100)" is what I tried, among other ways (from searching online, but I can't seem to get it to work.
I have two questions:
Does someone know what the correct code should be? and...
Can I reference the cell where the string is located and replace it in that same cell after doing the mid function without having to temporarily put it into another cell and copy and paste it back? For example, my string "123 - 456789" is in cell B2, is there a way to code it so I can reference cell B2 and simultaneous replace the cell B2 with "456789" and not having to place it in another cell then copy and paste it back into B2. I hope you get what i'm asking.
Thanks for you help!
This addresses part 2.
Sub strings()
Dim replace As String
Dim bCell As Range
For leftLoop = 2 To leftNumberOfCells
Set bCell = Range("B" & iRow)
replace = Mid(bCell, InStr(bCell, "-") + 2, 100)
Range("B" & iRow) = replace
iRow = iRow + 1
Next leftLoop
End Sub
Try this:
result = Split(TextToSplit, " ", 3)(2)
Split(TextToSplit, " ", 3) will split the text on spaces, returning a zero-based array. The last argument 3 limits the splitting to 3 portions: before the first space, between the first and second space, and everything else. The (2) at the end of the statement returns the last element of the array.
Hope that helps

Resources