I am trying to create a macro VBA that allow me for example:
Column A: 123456789101112 Column F : 6789101112
Only 10 characters in column F. If we have less than 10 characters in column A to complete with 0 for example:
Column A: 123458 Column F: 0000123458
This is the function that allow me to select the number of characters:
For i = 1 To table1Rows - 1
table1(1 + i, 6) = Right(table1(1 + i, 1), 15)
But I need to complete the 10 characters if I have less than 10 in column A.
This will place the formula in column F based on the amount of data in column A.
The formula uses r1c1 notation - R on its own means this row, C1 means column 1.
It's the same as writing =TEXT(RIGHT(A1,10),REPT(0,10)) and dragging down.
Sub Test()
Dim rLastRow As Range
With ThisWorkbook.Worksheets("Sheet1")
Set rLastRow = .Cells(.Rows.Count, 1).End(xlUp) 'Based on column A (column #1)
'Column A Offset by 5 columns is column F.
.Range(.Cells(1, 6), rLastRow.Offset(, 5)).FormulaR1C1 = _
"=TEXT(RIGHT(RC1,10),REPT(0,10))"
End With
End Sub
I think this is what you're after:
For i = 1 To table1Rows - 1
table1(1 + i, 6) = Format(Right(table1(1 + i, 1), 10), "0000000000")
Next
following code will add the remaing zero's to your string:
Dim strnbr As String
strnbr = 123
While Len(strnbr) < 10
strnbr = "0" + strnbr
Wend
Related
How do I extract only the first two letters and the 6 digit number from one cell to another? ie. Column 1 will have aa111111, bb222222, ccccc, dd12, eeee1
I only want to copy aa111111 and bb222222 in this case.
Thanks,
Alex
Try this short macro:
Sub KopyKat()
Dim N As Long, i As Long, K As Long
Dim s As String
N = Cells(Rows.Count, 1).End(xlUp).Row
K = 1
For i = 1 To N
s = Cells(i, 1).Value
If Len(s) = 8 _
And Mid(s, 1, 1) Like "[a-zA-Z]" _
And Mid(s, 2, 1) Like "[a-zA-Z]" _
And IsNumeric(Mid(s, 3)) Then
Cells(K, 2).Value = s
K = K + 1
End If
Next i
End Sub
If your strings are in A:A then in B1 (and copy down):
=IF(LEN(A1)>7,IF(AND(CODE(LOWER(MID(A1,{1,2},1)))<>CODE(UPPER(MID(A1,{1,2},1))),ISNUMBER(MID(A1,{3;4;5;6;7;8},1)*1)),LEFT(A1,8),""),"")
This is an array formula and must be confirmed with ctrl + shift + enter.
Running evaluate formula shows what happens and how it works :)
Using VBA then this will do:
Sub CopyMe()
Dim x As Variant, i As Long
For Each x In Range([A1], Cells(Rows.Count, 1).End(xlUp)).Value2
If x Like "[a-zA-Z][a-zA-Z]######" Then
i = i + 1
Cells(i, 2) = x
End If
Next
End Sub
Here is another way to do it. The formula loops through your string looking for a 6 digit number, at which point it takes the previous two characters (as long as they exist) and returns the 8 character string. Otherwise it returns an empty string.
=IFERROR(MID(A1,SUMPRODUCT(ROW($A$1:$A$100),--ISNUMBER(VALUE(MID(A1,ROW($A$1:$A$100),6))))-2,8),"")
Loops 100 times, so will work with strings up to a maximum length of 106 characters. To use the formula place your string in column A, and place this formula in cell B1 (for example) and drag down
I need to retrieve the last but one row value in column A/B(Value in Date)
Ex1: Row 3 : last column is AB. I need Row 3 Column AA value (Date) in Row 3 Column C.
Ex 2: Row 4:last column in AS: I need Column AR value (date) in ROw 4 column C.
Ex 3:Row 5:last column in BC: I need Column BB value (date) in ROw 5 column C.
there can b one or 2 blank values.
Please let me know if there are any excel formula to tackle this scenario.
with iteration you could use an array-formula like: (for row 3)
=INDIRECT("R3C"&MAX(COLUMN(3:3)*(LEN(3:3)>0))-1, 0)
without you need to exclude the cell itself... having it at column C it would be something like: (for row 3)
=INDIRECT("R3C"&MAX(COLUMN($D3:$ZZ3)*(LEN($D3:$ZZ3)>0))-1, 0)
if you want to simply auto fill the formula down then replace the "R3C" with "R"&ROW()&"C"
The formulas shown here are array formulas and must be confirmed with Ctrl+Shift+Enter.
If you get inclined to VBA, you could try something like this:
' In C3 type =GetSecondLastColumnValue()
' This function will keep on checking values on column at a time to the right
' If 3 continuous empty cells are found, it will assume that there are no more
' columns with values after that. The last known cell with value will be identified
' and value of column just to its left will be plugged in to column C
Public Function GetSecondLastColumnValue()
Dim Looper As Integer
Looper = 1
Const NoOfContinuousEmptyColumns As Integer = 3
Dim m_Address As String, m_LastKnownColumnWithValue
m_Address = Selection.Address
m_LastKnownColumnWithValue = m_Address
Do
m_Address = Range(m_Address).Offset(0, 1).Address
If Range(m_Address).Value = "" Then
Looper = Looper + 1
If Looper > NoOfContinuousEmptyColumns Then Exit Do
Else
Looper = 1
m_LastKnownColumnWithValue = m_Address
End If
Loop
m_LastKnownColumnWithValue = Range(m_LastKnownColumnWithValue).Offset(0, -1).Address
GetSecondLastColumnValue = Range(m_LastKnownColumnWithValue).Value
End Function
Example:
A B C D E F
1 abc def ab cd
2 abc def xy zx st
In C1, type =GetSecondLastColumnValue () and it will be populated with ab.
In C2, type the same formula and it will be populated with zx
This is just an example of what you can do with VBA. Do NOT use this function in production. It is insanely greedy and slow. It's just an illustration.
This subroutine is much faster:
' This method keeps on going to far right till it reaches the end of the columns
' Then it comes back to the last column with value, and hops to the column to its left, and remembers its value
' That value goes in column C. It loops through all rows you specify in startrow and endrow
Sub PopulateColumnC()
Dim StartRow As Integer, EndRow As Integer, RowLoop As Integer
StartRow = 1
EndRow = 3
Dim m_Address As String
For RowLoop = StartRow To EndRow
Range("A" & RowLoop).Select
m_Address = Selection.Address
Do
Selection.End(xlToRight).Select
If m_Address = Selection.Address Then
Selection.End(xlToLeft).Select
Exit Do
Else
m_Address = Selection.Address
End If
Loop
m_Address = Range(Selection.Address).Offset(0, -1).Address
Range("C" & RowLoop).Value = Range(m_Address).Value
Next
End Sub
I have an Excel file that contains some data in column B, now i wish to categories the data in A column like serial number first 1 to 5 again starts from 1 to 5 until the data ends,
for example in below format
1 A
2 B
3 C
4 D
5 E
1 F
2 G
3 H
4 I
5 J
1 K
2 L
3 M
4 N
5 O
I do not have existing code for above task please help me.
you can use the following
put 1 in the Cell A1
put =IF(OFFSET(A2,-1,0)=5,0,OFFSET(A2,-1,0))+1 in cell A2
double click in the bottom corner of cell A2, this will repeat the function for all cells in column A
hope that it will help you
Use some code
Sub DoItGood()
Dim rws As Long, rng As Range, t As Range
Columns(1).ClearContents
rws = Cells(Rows.Count, "B").End(xlUp).Row
Set rng = Range("A1:A" & rws)
x = 1
For Each t In Range("A1:A5")
t = t + x
x = x + 1
Next t
Range("A1:A5").AutoFill Destination:=rng, Type:=xlFillCopy
End Sub
You can get a repeated list of numbers from 1 to n downwards in rows with the following approach:
=MOD((ROW(A1)-1),n)+1
Take the integer remainder of the division row number (starting with 0) and n. You will get 0,1,2,...,n-1,0,1,2,...,n-1,0,1... To this add 1.
In your case n is 5:
=MOD((ROW(A1)-1),5)+1
filled downwards.
I have two columns of data as follows:
A1: A; A2: B; A3: C and B1: 1; B2:2; B3:3
Is there a simple loop in VBA to have on column C the concatenated values as:
C1: A1; C2: A2; C3: A3; C4: B1; C5: B2; C6: B3; etc?
I would use modulo arithmetic to achieve this. The subroutine below assumes that the last row in column C that needs to be populated is lLastRow (I set it =25 for testing):
Sub test()
Dim lLastRow As Long, ACnt As Long, BCnt As Long
ACnt = 1
' Last row of column C that needs to be filled with Data
lLastRow = 25
For BCnt = 1 To lLastRow
' Use modulo arithmetic to point to the right cell in column B
Cells(BCnt, 3) = Cells(ACnt, 1) & IIf(BCnt Mod 3 <> 0, BCnt Mod 3, 3)
' We should increment column A every three rows
ACnt = IIf((Cells(BCnt, 3).Row) Mod 3 = 0, ACnt + 1, ACnt)
' Reset column A pointer when we go beyond 3
ACnt = IIf(ACnt = 4, 1, ACnt)
Next BCnt
End Sub
Column B number:
The idea is that (starting from the first row), the modulo of each row and 3 will be 0,1,2 and will recycle in this fashion forever. Whenever the row number is a multiple of 3, the modulo returns 0 and therefore we need to refer to 3 on column B (i.e., cell (B3). Else, modulo returns exactly what we want (which is either 1 or 2).
Column A number:
This is simpler: every 3rd row we switch row.. So when (Cells(BCnt, 3).Row) Mod 3 = 0, we increment the pointer of column A. Of course, when we reach the 4th row, we need to return back to the 1st row.
I hope this helps!!
I prefer to avoid VBA when possible, so given a data setup like this:
The formula in cell C1 and copied down is:
=IF(ROW(A1)>COUNTA(A:B),"",INDEX(A:B,MOD(ROW(A1)-1,COUNTA(A:A))+1,1+(ROW(A1)>COUNTA(A:A))))
EDIT
As an alternate interpretation, pointed out by Ioannis, given a data setup like this:
The formula in cell C1 and copied down is:
=IF(ROW(A1)>COUNTA(A:A)*COUNTA(B:B),"",INDEX(A:A,INT((ROW(A1)-1)/COUNTA(B:B))+1)&INDEX(B:B,1+MOD(ROW(A1)-1,COUNTA(B:B))))
I can't see it any simpler than below
Sub concat()
Dim i As Integer
With ActiveSheet
For i = 1 To .UsedRange.Rows.Count
.Cells(i, 3) = .Cells(i, 1) & .Cells(i, 2)
Next i
End With
End Sub
Or maybe there is:
Sub concat2()
With ActiveSheet
.Range("C1") = "=CONCATENATE(RC[-2],RC[-1])"
.Range("C1").AutoFill Destination:=.Range("C1:C" & .UsedRange.Rows.Count)
End With
End Sub
That would also make non-vba users understand what column C actually is ;)
Can't you do something like:
Dim i,j AS int
For i = 1 to 3
For j = 1 to 6
NewVal = C(j):A(i)
Next j
Next i
This is untested, but gives you direction of where to go..
I need some help converting three colums into a matrix using excel macro.
Here is an example:
From this:
A A 0
A B 23
A C 3
B A 7
B B 56
B C 33
C A 31
C B 6
C C 5
to this:
A B C
A 0 23 3
B 7 56 33
C 31 6 5
Hope you can help me.
Thanks
Not quite sure what exactly you are meaning by matrix. For the code below I assumed you were looking for a way to read the data in the first two columns as Row and Column data of the output table. Assume the input data is in the Columns 1 - 3 of "Sheet1"
Sub ConvertTableOfData()
Dim testArray(1 to 3)
Dim chkROW as Integer
Dim chkCOL as Integer
Dim chkVAL as Integer
'// index the Row and Column headers
testArray(1) = "A"
testArray(2) = "B"
testArray(3) = "C"
'// Iterate through every row in the initial dataset
For i = 1 to Worksheets("Sheet1").Cells(1, 1).End(xlDown).Row
With Worksheets("Sheet1")
'// Assign the Output Row and Column values
'// based on the array indices
For j = 1 to UBound(testArray, 1)
If .Cells(i, 1) = testArray(j) Then
chkROW = j
End If
If .Cells(i, 2) = testArray(j) Then
chkCOL = j
End If
Next j
'// store the actual value
chkVAL = .Cells(i, 3)
End With
'// output table (in Sheet2)
With Worksheets("Sheet2")
.Cells(chkROW, chkCOL) = chkVAL
End With
Next i
'// Add headers to Output table
For i = 1 to 3
With Worksheets("Sheet2")
.Cells(i + 1, 1) = testArray(i)
.Cells(i, i + 1) = testArray(i)
End With
Next i
End Sub
You can also perform this without VBA.
Assume your table of data is in the range A1:C9.
Assume the first number (0) in the 3 by 3 grid of data is cell F3, with A, B, C in the row above, and A, B, C in the column to the left.
Enter the formula in cell F3 as
=INDEX($C$1:$C$9,SUMPRODUCT(--($A$1:$A$9=$E3),--($B$1:$B$9=F$2),ROW($A$1:$A$9)))
Copy this formula to all 9 cells in the 3 by 3 grid.
This generalized to any size of data.