VBA- Concatenate Cells with If function - excel

I have a code that returns all the data I want from a query. The problem is that the csv format separates the data, even account names with commas in them. For each row, column A is the account name followed by 11 blocks of integer data (making a total of 12 cells used per row). Fortunately, for the accounts that have commas, the result is only one additional cell (making a total of 13 cells used per row).
I need an IF-THEN formula that will concatenate Column A & Column B if there are 13 used cells in that row, otherwise leaving things alone. Being new to VBA concatenate is giving me huge problems.
Any suggestions? Thanks in advance.

Well, just from a term point of view, Excel Formulas and Excel VBA are not the same thing.
In fact, there are a lot of people on here that are formula pros that know nothing about VBA and visa versa.
That being said, you could use something like:
=IF(COUNTBLANK(C1:N1)=0,A1&" "&B1,A1)
Of course, assuming your data looks like this:
It would be easier to use:
=IF(N1="",A1,A1&" "&B1)
Concatenating in Excel formulas and VBA is pretty simple.
Simply separate the strings you wish to concatenate with an amperstand &
If I want to concatenate A1 and B1, I can use =A1&B1 as shown in the formula.
If I want to add a space, or even a word, I can just add it between them as a string:
=A1&" is way cooler than "&B1
Edit:
VBA:
Sub ConcatenateCells()
Application.ScreenUpdating = False
Dim FixRange As Range, c As Range
Set FixRange = Range("A1:A" & ActiveSheet.UsedRange.Rows.Count)
For Each c In FixRange
If InStr(c, ",") > 0 Then c = c & c.Offset(0, 1)
'You could also add a space between the two using c = c & " " & c.Offset(0, 1)
Next c
Application.ScreenUpdating = True
End Sub
I don't know if you want to scoot the data over after you have concatenated the values, but if you do, you can use this:
Sub ConcatenateAndScootCells()
Dim FixRange As Range, c As Range
Set FixRange = Range("A1:A" & ActiveSheet.UsedRange.Rows.Count)
For Each c In FixRange
If InStr(c, ",") > 0 Then
c = c & c.Offset(0, 1)
c.Offset(0, 1).Delete xlToLeft
End If
Next c
End Sub
Still assuming I got your data format right, here is what the before and after looks like:
Final Edit:
If you absolutely insist on counting the number of used rows instead of simply looking for a coma in column A, then use this:
Sub ConcatenateAndScootCells()
Dim FixRange As Range, c As Range
Set FixRange = Range("A1:A" & ActiveSheet.UsedRange.Rows.Count)
For Each c In FixRange
If Cells(c.row, Columns.Count).End(xlToLeft).Column = 13 Then
c = c & " " & c.Offset(0, 1)
c.Offset(0, 1).Delete xlToLeft
End If
Next c
End Sub

Related

Lookup using dynamic filename in VBA [duplicate]

Can anyone solve this?
Sub test
Dim i as integer
For I = 1 to 10
ActiveCell.Offset(0, 2).Formula = "=Sum(E15,&i&)"
Next I
End Sub
your actual goal is unclear
you may want to start form this code
Sub test()
Dim i As Integer
For i = 1 To 10
cells(i, 4).Formula = "=Sum(E" & i & ":E15)"
Next
End Sub
and adjust it to your needs, knowing that:
it currently writes in cells "D1:D10"
since cells(i, 4) references a cell in 4th column (i.e.: column "D") 4 and i row, and we're inside a loop where i is looping through 1 to 10
so if:
you want to reference a different column then just change 4 to the proper column index
you want to reference a different row then just change i to the proper row index (may be some i+2 if you need to iterate through 1 to 10 but start writing from row 3)
the formula written in those cells is:
=SUM(E1:E15) in D1,
=SUM(E2:E15) in D2,
....
=SUM(E10:E15) in D10.
so just change "=Sum(E" & i & ":E15)" to your actual needs
You're close, trying to use ampersands (&) to concatenate strings.
ActiveCell.Offset(0, 2).Formula = "=Sum(E15," & i & ")"
Use the ampersands between strings to merge them, not inside strings.

Vlookup with dynamic col num index [duplicate]

Can anyone solve this?
Sub test
Dim i as integer
For I = 1 to 10
ActiveCell.Offset(0, 2).Formula = "=Sum(E15,&i&)"
Next I
End Sub
your actual goal is unclear
you may want to start form this code
Sub test()
Dim i As Integer
For i = 1 To 10
cells(i, 4).Formula = "=Sum(E" & i & ":E15)"
Next
End Sub
and adjust it to your needs, knowing that:
it currently writes in cells "D1:D10"
since cells(i, 4) references a cell in 4th column (i.e.: column "D") 4 and i row, and we're inside a loop where i is looping through 1 to 10
so if:
you want to reference a different column then just change 4 to the proper column index
you want to reference a different row then just change i to the proper row index (may be some i+2 if you need to iterate through 1 to 10 but start writing from row 3)
the formula written in those cells is:
=SUM(E1:E15) in D1,
=SUM(E2:E15) in D2,
....
=SUM(E10:E15) in D10.
so just change "=Sum(E" & i & ":E15)" to your actual needs
You're close, trying to use ampersands (&) to concatenate strings.
ActiveCell.Offset(0, 2).Formula = "=Sum(E15," & i & ")"
Use the ampersands between strings to merge them, not inside strings.

Dynamic SUM Range Formula [duplicate]

Can anyone solve this?
Sub test
Dim i as integer
For I = 1 to 10
ActiveCell.Offset(0, 2).Formula = "=Sum(E15,&i&)"
Next I
End Sub
your actual goal is unclear
you may want to start form this code
Sub test()
Dim i As Integer
For i = 1 To 10
cells(i, 4).Formula = "=Sum(E" & i & ":E15)"
Next
End Sub
and adjust it to your needs, knowing that:
it currently writes in cells "D1:D10"
since cells(i, 4) references a cell in 4th column (i.e.: column "D") 4 and i row, and we're inside a loop where i is looping through 1 to 10
so if:
you want to reference a different column then just change 4 to the proper column index
you want to reference a different row then just change i to the proper row index (may be some i+2 if you need to iterate through 1 to 10 but start writing from row 3)
the formula written in those cells is:
=SUM(E1:E15) in D1,
=SUM(E2:E15) in D2,
....
=SUM(E10:E15) in D10.
so just change "=Sum(E" & i & ":E15)" to your actual needs
You're close, trying to use ampersands (&) to concatenate strings.
ActiveCell.Offset(0, 2).Formula = "=Sum(E15," & i & ")"
Use the ampersands between strings to merge them, not inside strings.

Need to exclude a word (or number of characters) in my code

I am trying to create a Module that will format an excel spreadsheet for my team at work. There is one column that will contain the word "CPT" and various CPT codes with descriptions.
I need to delete all text (CPT description) after the 5 digit CPT code but alsp keep the word CPT in other cells.
For example: Column S, Row 6 contains only the word "CPT" (not in quotations)
Then Column S, Row 7 contains the text "99217 Observation Care Discharge"
This setup repeats several times throughout Column S.
I would like for Row 6 to stay the same as it is ("CPT") but in Row 7 i only want to keep "99217"
Unfortunately, this is not possible to do by hand as there are several people who will need this macro and our spreadsheets can have this wording repeated hundreds of times in this column with different CPT codes and descriptions.
I have tried various If/Then statements, If/Then/Else
Sub CPTcolumn()
Dim celltxt As String
celltxt = ActiveSheet.Range("S6" & Rows.Count).End(xlUp).Text
Dim LR As Long, i As Long
LR = Range("S6" & Rows.Count).End(xlUp).Row
For i = 1 To LR
If InStr(1, celltxt, "CPT") Then
Next i
Else
With Range("S6" & i)
.Value = Left(.Value, InStr(.Value, " "))
End With
Next i
End If
End Sub
When i try to run it I get Various "Compile Errors"
I would do this differently.
Given:
The cell to be modified will be the cell under a cell that contains CPT
in the algorithm below, we look for CPT all caps and only that contents. Easily modified if that is not the case.
Since you write " a five digit code", we need only extract the first five characters.
IF you might have some cells that contain CPT where the cell underneath does not contain a CPT code, then we'd also have to check the contents of the cell beneath to see if it looked like a CPT code.
So we just use the Range.Find method:
Sub CPT()
Dim WS As Worksheet, R As Range, C As Range
Dim sfirstAddress As String
Set WS = Worksheets("sheet4")
With WS.Cells
Set R = .Find(what:="CPT", LookIn:=xlValues, lookat:=xlWhole, _
MatchCase:=True)
If Not R Is Nothing Then
sfirstAddress = R.Address
Set C = R.Offset(1, 0)
C.Value = Left(C.Value, 5)
Do
Set R = .FindNext(R)
If Not R.Address = sfirstAddress Then
Set C = R.Offset(1, 0)
C.Value = Left(C.Value, 5)
End If
Loop Until R.Address = sfirstAddress
End If
End With
End Sub
If this sequence is guaranteed to only be in Column S, we can change
With WS.Cells
to With WS.Columns(19).Cells
and that might speed things up a bit.
You may also speed things up by adding turning off ScreenUpdating and Calculation while this runs.
Your first error will occur here:
ActiveSheet.Range("S6" & Rows.Count).End(xlUp).Text
Because you're trying to retrieve text from the last used range starting .End(xlUp) at Range("S61048576"), which is roughly 58 times the row limit in Excel. You might change Range("S6" & Rows.Count) to Range("S" & Rows.Count)
Your second error will occur here:
LR = Range("S6" & Rows.Count).End(xlUp).Row
Which will be the same error.
The third error will occur here:
For i = 1 To LR
If InStr(1, celltxt, "CPT") Then
Next i
You cannot nest half of an If-End If block in a For-Next loop, or vice-versa and you've done both. If you want to iterate and perform an If-End If each iteration, you need to contain the If-End If within the For-Next like
For i = 1 To LR
If InStr(1, celltxt, "CPT") Then
'Is the purpose here to do nothing???
Else
With Range("S" & i)
.Value = Left(.Value, InStr(.Value, " "))
End With
End If
Next i
EDIT:
For technical accuracy, your first error would actually be your broken up For-Next and If-End If, as you wouldn't even be able to compile to execute the code to run into the other two errors.
You can simply use the Mid function in the worksheet.
As I understood from your question that you need to separate numbers and put them in other cells, is this true?
To do this, you can write this function in cell R6 like this
=Mid(S6,1,5)
Then press enter and drag the function down and you will find that all the cells containing numbers and texts have been retained numbers in them

Create new Excel rows based on column data

Good afternoon all,
I have an issue where I have users who have multiple bank account details. I need to try and create a new row for each employee who has more than one bank account, with the second bank account being allocated a new row.
Employee Number User ID BSB Account number
10000591 WOODSP0 306089,116879 343509,041145273
10000592 THOMSOS0 037125 317166
I need it to look something like this:
Employee Number User ID BSB Account number
10000591 WOODSP0 306089 343509
10000591 WOODSP0 116879 041145273
10000592 THOMSOS0 037125 317166
Any thoughts? Your input is greatly appreciated!
Screenshots are here to demonstrate:
Right click on the tab and choose "View Code"
Paste this code in:
Sub SplitOnAccount()
Dim X As Long, Y As Long, EmpNo As String, UserID As String, BSB As Variant, AccNo As Variant
Range("F1:I1") = Application.Transpose(Application.Transpose(Array(Range("A1:D1"))))
For X = 2 To Range("A" & Rows.Count).End(xlUp).Row
EmpNo = Range("A" & X).Text
UserID = Range("B" & X).Text
BSB = Split(Range("C" & X).Text, ",")
AccNo = Split(Range("D" & X).Text, ",")
For Y = LBound(AccNo) To UBound(AccNo)
Range("F" & Range("F" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = EmpNo
Range("G" & Range("G" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = UserID
Range("H" & Range("H" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = BSB(Y)
Range("I" & Range("I" & Rows.Count).End(xlUp).Row).Offset(1, 0).Formula = AccNo(Y)
Next
Next
End Sub
Close the window to go back to excel
Press ALT-F8
Choose SplitOnAccount and click run.
Note, this is going to populate the split data to rows F to I, make sure there is nothing in there. If there is post back and we can change it.
Also format columns F - I as text before you run it or Excel will strip leading zeros off as it will interpret it as a number.
Here is another sub that appears to perform what you are looking for.
Sub stack_accounts()
Dim rw As Long, b As Long
Dim vVALs As Variant, vBSBs As Variant, vACTs As Variant
With ActiveSheet '<-define this worksheet properly!
For rw = .Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1
vVALs = .Cells(rw, 1).Resize(1, 4).Value
vBSBs = Split(vVALs(1, 3), Chr(44))
vACTs = Split(vVALs(1, 4), Chr(44))
If UBound(vBSBs) = UBound(vBSBs) Then
For b = UBound(vBSBs) To LBound(vBSBs) Step -1
If b > LBound(vBSBs) Then _
.Rows(rw + 1).Insert
.Cells(rw - (b > LBound(vBSBs)), 1).Resize(1, 4) = vVALs
.Cells(rw - (b > LBound(vBSBs)), 3).Resize(1, 2).NumberFormat = "#"
.Cells(rw - (b > LBound(vBSBs)), 3) = CStr(vBSBs(b))
.Cells(rw - (b > LBound(vBSBs)), 4) = CStr(vACTs(b))
Next b
End If
Next rw
End With
End Sub
I was originally only going to process the rows that had comma delimited values in columns C and D but I thought that processing all of them would allow the macro to set the Text number format and get rid of the Number as text error warnings and keep the leading zero in 041145273.
        
You Can definitely use Power Query to transform the data to generate new rows using split column option.
Check this article it explains the process in detail.
Load Data in Power Query section of excel.
Create an Index (Not required step)
Use Split column function with advance options and split them into new rows.
Save this result into new table for your use.
I did it myself and it worked like a charm.
A formula solution:
Delimiter: Can be a real delimiter or an absolute reference to a cell containing only the delimiter.
HelperCol: I have to use a helper column to make it work. You need to give the column letter.
StartCol: The column letter of the first column containing data.
SplitCol: The column letter of the column to be splitted.
Formula1: Used to generate the formula for the first column not to be splitted. You can fill this formula down and then fill to right.
Formula2: Used to generate the formula for the column to be splitted(only support split one column).
Formula3: Used to generate the formula for the Helper column.
(If the title of the column to be splitted contains the delimiter, you must change the first value of the helper column to 1 manually.)
Formula1:=SUBSTITUTE(SUBSTITUTE("=LOOKUP(ROW(1:1),$J:$J,A:A)&""""","$J:$J","$"&B2&":$"&B2),"A:A",B3&":"&B3)
Formula2:=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE("=MID($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,"&"""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)))+1,FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)+1))-FIND(""艹"",SUBSTITUTE($M$1&LOOKUP(ROW(A1),$J:$J,F:F)&$M$1,$M$1,""艹"",ROW(A2)-LOOKUP(ROW(A1),$J:$J)))-1)&""""","$M$1",IF(ISERROR(INDIRECT(B1)),""""&B1&"""",B1)),"$J:$J","$"&B2&":$"&B2),"F:F",B4&":"&B4)
Formula3:=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE("=SUM(E1,LEN(B1)-LEN(SUBSTITUTE(B1,$H$1,"""")))+1","B1",B4&1),"$H$1",IF(ISERROR(INDIRECT(B1)),""""&B1&"""",B1)),"E1",B2&1)
Helper must filled one row more than the data.
How to use:
Copy the formula generated by the above three formula.
Use Paste Special only paste the value.
Make the formula into effect.
Fill the formula.
Bug:
Numbers will be converted to Text. Of course you can remove the &"" at the end of the formula, but blank cells will be filled with 0.
ps. This method may by very hard to comprehend. But once you master it, it can be very useful to solve relative problems.

Resources