Excel VBA code for categories the data - excel

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.

Related

Generate a Matrix B, whose elements B i j are the average of row i and column j of Matrix A

I have a task to do which includes:
Reading a matrix from a txt file and printing it - I managed to do this solo
Generate a Matrix B, whose elements B i j are the average of row i and column j of Matrix A.
Here is the prob for me.
I have idea how this would happen, but I cant write it.
Example:
Matrix A 3 3 Matrix B ( the first element B11 should be equal to average of Row 1 of Matrix A
2 4 6 ( 2+ 4+6) plus average of Column 1 of Matrix A ( 2+ 8+6).
8 4 2 ((2+4+6) + (2+8+6)) /2 and this should be applicaple for every element based on
6 8 2 its place (Element b23 is avg of sum of row 2 and column3 )
This should happen in excel VBA
Thank you in advance!
This is the code i managed to do solo:
your text
The below is an example of how to create a new matrix as requested. The code includes some dummy text to read an array from a sheet (range B4:D7) then print the result to the sheet (starting in cell K4), so obviously you will want to remove those and integrate with your own code for loading the matrix. I'm assuming you are reading the array in as if it was copied from Excel, i.e. as a 2D array with each index starting at 1. It should be easy to modify for other data forms following the logic below.
Sub temp()
'Assume A is a 1-indexed 2D array, just as if a range is copied from an Excel sheet
Dim A As Variant
A = Range("B4:D7").Value
Dim numRows As Long
Dim numCols As Long
numRows = UBound(A, 1)
numCols = UBound(A, 2)
ReDim rowSum(1 To numCols) As Double
ReDim colSum(1 To numRows) As Double
'First we want to get the sum of each row and column
Dim r As Long
Dim c As Long
For r = 1 To numRows
For c = 1 To numCols
rowSum(c) = rowSum(c) + A(r, c)
colSum(r) = colSum(r) + A(r, c)
Next
Next
'Now create the average of the row sum and column sum in each element of a new array B
ReDim B(1 To numRows, 1 To numCols) As Double
For r = 1 To numRows
For c = 1 To numCols
B(r, c) = (rowSum(c) + colSum(r)) / 2
Next
Next
'Just for checking the results
Range("k4").Resize(numRows, numCols) = B
End Sub

Separating responses from multiple response survey into separate columns with sorting

I need help separating responses from a survey into different columns. Each "check all that apply" question has the responses from each respondent in one cell (e.g. 1,3,4 or 1,2 or 2,4, etc.). For example, I want to create x number of columns for all the answer choices, then code the responses 'yes' or 'no' in excel.
Q2
1,2,3
2,3,4
3,4
1,3,4
1,2,4
...
I learned how to separate the column by comma using Text to column but this is the code after I separate it:
Q2
1 2 3
2 3 4
3 4
1 3 4
1 2 4
...
What I want is each column have a similar value per row. Here is an example :
Q2
1 2 3
2 3 4
3 4
1 3 4
1 2 4
...
Is there a way to do it without moving each cell manually since there is like 100 answer? Thanks
For Office 365 Insider Channel:
=LET(ζ,0+TEXTSPLIT(A1,","),XLOOKUP(SEQUENCE(,MAX(ζ)),ζ,ζ,""))
Copy down to get similar results for the strings in A2, A3, etc.
If you didn't have access to Office 365 insider, you could do a similar thing using Split in VBA:
Sub test()
Dim LString As String
Dim LArray() As String
' Change to Long for larger ranges (question only required 100 rows)
Dim i As Integer, j As Integer, k As Integer, lastElement As Integer, LR As Integer
Const LC = 5
LR = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To LR
LString = Cells(i, 1)
LArray = Split(LString, ",")
lastElement = UBound(LArray, 1)
k = 0
For j = 1 To LC
If k > lastElement Then
Exit For
Else
If LArray(k) = j Then
Cells(i, j + 1) = LArray(k)
k = k + 1
End If
End If
Next j
Next i
End Sub
Assumes responses in each row are in ascending order and output range is initially blank.

Selecting only 10 characters (right) on vba excel

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

Concatenate cells in excel

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..

how to transform three columns to a matrix using macro

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.

Resources