I'm doing a script where i can count the data from a column if the data duplicate is >3 i will tag it..
My problem is that i need to put a conditional statement where i can count the data within a date range of 1 Month..
Sample Input File:: (mm/dd/yyyy)
Column A | Column B | Column C| Column D
023 | 1/2/2016 | |
023 | 1/3/2016 | |
023 | 1/4/2016 | |
024 | 2/1/2016 | |
024 | 3/1/2016 | |
024 | 4/1/2016 | |
Sample Output File:
Column A | Column B | Column C| Column D
023 | 1/2/2016 | |
023 | 1/3/2016 | |
023 | 1/4/2016 | 1 | 3
024 | 2/1/2016 | |
024 | 3/1/2016 | |
024 | 4/1/2016 | |
If the duplicate data is not within a month range it will not be tag..
What i expect the code to do is count the data from Column A if the data is >3 and the date of all that data from Column B is within a month tag it from Column D and E not all the row but the recent date from Column B
What my code do is count the data from Column A if the data is >3 it will be tag from Column C and D from most recent date from Column B
My code:
Dim i1 As Long, lastRow As Long, countRow As Long
lastRow = Sheet2.Range("T" & Rows.Count).End(xlUp).Row
'xDate = Sheet2.Range("C" & lastRow)
For i1 = 1 To lastRow
If countRow > 2 Then
countRow = Application.CountIf(Sheet2.Columns(20), Sheet2.Cells(i1, 20))
If countRow > 2 Then
If Not CBool(Application.CountIfs(Sheet2.Columns(20), Sheet2.Cells(i1, 20), _
Sheet2.Columns(85), ">" & Sheet2.Cells(i1, 85))) Then _
Sheet2.Cells(i1, 86).Resize(1, 2) = Array("1", "3")
End If
End If
Next i1
Note:
In my code i didn't use Column A B C D instead it's Column T CG CH CI
I don't know how to range it to a month, i tried collection but still new to VBA and I'm not familiar with it and i don't know if it's the right thing..
edited: left only code as per last OP's specs and with a formula correction
you could try this
Sub sbFindDuplicatesInColumn_C3ter()
With ThisWorkbook.Worksheets("duplicates") '<~~ you should know what workbook and worksheet you are on!!
With .Range("T1").Resize(.Range("T" & .Rows.Count).End(xlUp).Row) ' the "base" column is column "T"
With .Offset(, 67) ' column "CI" is 67 columns away from column "T"
.FormulaR1C1 = "=IF(COUNTIFS(C20, RC20, C72,""<="" & EOMONTH(RC72,0), C72,"">="" & EOMONTH(RC72,-1)+1 )>2, IF(COUNTIFS(C20, RC20,C72,"">"" &RC72,C72,""<="" & EOMONTH(RC72,0))=0, 3 , """") , """")" ' substituted relative references with absolute ones : column "T" has index 20, column "BT" has index 72
.Value = .Value '<== if you want to get rid of formulas
End With
With .Offset(, 66) ' column "CH" is 66 columns away from column "T"
.FormulaR1C1 = "=IF(RC[1]>0, 1, """") " ' I left relative references since columnn "CH" is always one left of column "CG" as was for columns "A" and "B"
.Value = .Value '<== if you want to get rid of formulas
End With
End With
End With
End Sub
This input ...
generated this output ...
from this code ...
Option Explicit
Sub main()
Dim iLoop As Long, jLoop As Long
Dim lastRow As Long, countRow As Long
Dim myDate1 As Variant, myDate2 As Variant
lastRow = Sheet1.Range("A" & Rows.Count).End(xlUp).Row
For iLoop = 1 To lastRow
countRow = Application.CountIf(Sheet1.Range(Sheet1.Cells(iLoop, 1), Sheet1.Cells(lastRow, 1)), Sheet1.Cells(iLoop, 1))
If countRow > 2 Then
For jLoop = lastRow To (iLoop + 1) Step -1
If Sheet1.Cells(jLoop, 1).Value = Sheet1.Cells(iLoop, 1).Value Then
myDate1 = Application.EDate(Sheet1.Cells(iLoop, 2), 3)
myDate2 = Sheet1.Cells(jLoop, 2)
If myDate2 > myDate1 Then Sheet1.Cells(jLoop, 3).Resize(1, 2) = Array("1", "3")
Exit For
End If
Next jLoop
End If
Next iLoop
End Sub
Specifically, using the worksheet function EDate to add three months to the first date found for a given item number.
Also, shortening the size of the list the worksheet function CountIf uses as the loop counter iLoop progresses.
As an aside, in your code snippet you used i1 as a loop counter. It is easy to confuse this with il. 8)
Related
I would like to create a VBA macro that will auto number all cells in column 'A' to a single decimal place, if and only if they have a value in column 'B'. Every time there is a row that does not have a value in column 'B', column 'A' should re-start numbering at the next integer.
IE:
|COLUMN A | COLUMN B|
|:-------:|:-------:|
| 1.1 | TEXT |
| 1.2 | TEXT |
| 1.3 | TEXT |
| 1.4 | TEXT |
| 1.5 | TEXT |
| | *NO TEXT* |
| 2.1 | TEXT |
| 2.2 | TEXT |
| 2.3 | TEXT |
| | *NO TEXT* |
| 3.1 | TEXT |
| 3.2 | TEXT |
| 3.3 | TEXT |
| 3.4 | TEXT |
I think this is pretty self-explanatory, but post up if anything confuses you:
Option Explicit
Private Sub numberCells()
Dim totalRows As Long
Dim i As Long
Dim baseNumber As Long
Dim count As Integer
totalRows = ActiveSheet.UsedRange.Rows.count
baseNumber = 1
i = 2
Do While i <= totalRows
If Range("B" & i).Value <> "" Then
count = count + 1
Range("A" & i).Value = baseNumber & "." & count
Else
baseNumber = baseNumber + 1
count = 0
End If
i = i + 1
Loop
End Sub
I like using .Areas,
Here's my version
Sub Do_It_Good()
Dim RangeArea As Range, c As Range, LstRw As Long, sh As Worksheet, Rng As Range
Set sh = Sheets("Sheet1")
With sh
LstRw = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
Set Rng = .Range("B2:B" & LstRw)
y = 0
For Each RangeArea In Rng.SpecialCells(xlCellTypeConstants, 23).Areas
y = y + 1
x = 0
For Each c In RangeArea.Cells
c.Offset(, -1) = y & "." & 1 + x
x = x + 1
Next c
Next RangeArea
End With
End Sub
The script that i want is to count the duplicate values in a column, if value is greater than 2 tag it to the last column as "updated" based on the date column closest to the current date.
example:
Column A | Column B | Column C
1 | 1/2/2016 |
2 | 1/3/2016 |
3 | 1/4/2016 |
1 | 1/5/2016 |
1 | 1/6/2016 |
output:
Column A | Column B | Column C
1 | 1/2/2016 |
2 | 1/3/2016 |
3 | 1/4/2016 |
1 | 1/5/2016 |
1 | 1/6/2016 | updated
In this example the value 1 in Column A have duplicate value >2 so in Column C which is the last column it will be tag as updated...
there are three 1 in Column A but the closest date now is 1/6/2016 so it is the one that been tagged... if <2 no action done..
Here's my code:
Sub sbFindDuplicatesInColumn_C()
Dim lastRow As Long
Dim countRow As Long
Dim iCntr As Long
Dim CurDate As Date
lastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
For iCntr = 1 To lastRow
If Cells(iCntr, 1) > 3 Then
countRow = WorksheetFunction.Match(Cells(iCntr, 1), Range("A1:A" & lastRow), 0)
If iCntr <> countRow Then
If CurDate <> iCntr Then
Cells(iCntr, 3) = "Updated"
End If
End If
End If
Next
End Sub
my code is not working but it doesn't give any error.
Your narrative contradicts your sample results in that there are not 'greater than 3' for any of the data. I'll just assume that is a typo and you meant 'greater than 2'.
A WorksheetFunction object's COUNTIF function can readily detmine the frequency of the value in column A. While it is possible to evaluate an array formula to determine the maximum date from column B, in reality you only want to determine whether there are any dates later than the one being examined. If there aren't you have the latest date. A COUNTIFS function can determine this faster than an array formula.
Sub sbFindDuplicatesInColumn_C()
Dim i As Long, lastRow As Long, countRow As Long
With Worksheets("Sheet2") '<~~ you should know what worksheet you are on!!
lastRow = .Range("A" & Rows.Count).End(xlUp).Row
For i = 1 To lastRow
countRow = Application.CountIf(.Columns(1), .Cells(i, 1))
If countRow > 2 Then
If Not CBool(Application.CountIfs(.Columns(1), .Cells(i, 1), _
.Columns(2), ">" & .Cells(i, 2))) Then _
.Cells(i, 3) = "updated"
End If
Next i
End With
End Sub
as an alternative solution
Option Explicit
Sub sbFindDuplicatesInColumn_C2()
With ThisWorkbook.Worksheets("duplicates") '<~~ you should know what workbook and worksheet you are on!!
With .Range("A1").Offset(, 2).Resize(.Range("A" & .Rows.Count).End(xlUp).Row)
.FormulaR1C1 = "=IF(COUNTIF(C1,RC[-2])>2, IF(COUNTIFS(C1, RC[-2],C2," & """" & ">" & """" & "&" & "RC[-1])=0," & """" & "updated" & """" & "," & """" & """" & ")," & """" & """" & ")"
.Value = .Value '<== if you want to get rid of formulas
End With
End With
End Sub
it differs form Jeeped's one in that it doesn't iterate through cells. but it writes in every cells twice (first time to put formula in it and the second time to change it into a value to keep only needed markings) although in two statements only.
It'd be fine to know which is the fastest
First, Let me tell you the script that i want to achieve. I need a script that will count the values within a date range the range of date is 3 months, I have a source file which contains 3 months of data now i need to count the data by months if the data is within the months(3) tagged it as selected..(at least one value per month(up to 3))
Sample:
`Header A|Header B |Header C|
white | 1/1/2016 | |
white | 2/2/2016 | |
white | 3/3/2016 | |
black | 1/1/2016 | |
black | 2/2/2016 | |
grey | 3/3/2016 | |
grey | 3/3/2016 | |
grey | 4/4/2016 | |
brown | 4/4/2016 | |
brown | 4/4/2016 | |
brown | 5/5/2016 | |
brown | 6/6/2016 | |
Sample Output:
`Header A|Header B |Header C|
white | 1/1/2016 | |
white | 2/2/2016 | |
white | 3/3/2016 |selected|
black | 1/1/2016 | |
black | 2/2/2016 | |
grey | 3/3/2016 | |
grey | 3/3/2016 | |
grey | 4/4/2016 | |
brown | 4/4/2016 | |
brown | 4/4/2016 | |
brown | 5/5/2016 | |
brown | 6/6/2016 |selected|
In the sample above. The data white has been tagged as selected because it meets the required criteria, let's say the criteria needed is "at least one color per month" we have 3 month of data so it needs to count 1 color per month. The other color in the ex. didnt meet the criteria like the color black it only have data for 2 months what we need is for 3 months. The color grey have 3 data if you count it will only return 2 months because there is 2 data in a month. The color brown meets the criteria because there is a data for 3 months duplicate value in a month is fine as long it has a data every months(3) for..
Now here's my code:
'iterate all rows for 3 months to check their dates then create an arbitrary column(lastcolumn +1) to store the month value
For rownum = 2 To lastrow_masterfile
varDatesValue = masterfileWKsht.Range("B" & rownum).Value
masterfileWKsht.Range("D" & rownum).Value = Month(varDatesValue)
Next
'column range for color
Set myRangeColor = ThisWorkbook.Sheets("masterfile").Range("A2:A" & lastrow_masterfile)
'column range for (arbitrary column)monthvalue
Set myRangeMonthValue = ThisWorkbook.Sheets("masterfile").Range("D2:D" & lastrow_masterfile)
'loop for weekly data
For rownum_weekly = startingrow_of_weekly To lastRow
varColors = masterfileWKsht.Range("B" & rownum_weekly).Value
varCOMMonth = Month(masterfileWKsht.Range("A" & rownum_weekly).Value)
'CountIfs 1:
varMonth1 = WorksheetFunction.CountIfs(myRangeColor, varColor, myRangeMonthValue, varDatesValue)
'CountIfs 2:
'month value of varDates per row -1 for previous month(range of this is the new column which store the monthvalue)
varMonth2 = WorksheetFunction.CountIfs(myRangeColor, varColor, myRangeMonthValue, varDatesValue - 1)
'CountIfs 3:
'month value of varDates per row -2 for 2months ago(range of this is the new column which store the monthvalue)
varMOnth3 = WorksheetFunction.CountIfs(myRangeColor, varColor, myRangeMonthValue, varDatesValue - 2)
'if value of the 3 countifs is atleast 1 then tagged it as selected
If varMonth1 >= 1 And varMonth2 >= 1 And varMOnth3 >= 1 Then
'insert code here(i still dont khow how to write code here)
End If
Next
please help me about this....
Formula Solution
Although I acknowledge that you are looking for a VBA solution to this (perhapse for a good reason), I want to point out that you can solve this by using formulas. You could get the result you are looking for by using an array formula like:
{=IF(SUM(IF(FREQUENCY(($A$2:$A$13=A2)*(MONTH($B$2:$B$13)),($A$2:$A$13=A2)*(MONTH($B$2:$B$13)))>0,1))>3,"Selected","")}
This will return Selected if the color is found in at least three different months.
To use this, type the formula in cell C2, commit by pressing CTRL+SHIFT+ENTER (since it is an array formula) and drag the formula down along side of your data.
VBA+Formula Solution
As you commented that you need this applied in a generated report, you could simply use VBA to type the formula into the sheet:
Sub AddFormula()
Dim MstrSht As Worksheet
Dim ColorRng As Range
Dim DateRng As Range
Dim i As Integer
Set MstrSht = ThisWorkbook.Sheets("masterfile")
'Set Color Range and Date Range
Set ColorRng = MstrSht.Range("A2:A" & MstrSht.Cells(Rows.Count, 1).End(xlUp).Row)
Set DateRng = MstrSht.Range("B2:B" & MstrSht.Cells(Rows.Count, 1).End(xlUp).Row)
'Add Formula to cells in column C
For i = 2 To MstrSht.Cells(Rows.Count, 1).End(xlUp).Row
MstrSht.Cells(i, 3).FormulaArray = "=IF(SUM(IF(FREQUENCY((" & ColorRng.Address & "=A" & i & " )*(MONTH(" & DateRng.Address & ")),(" & _
ColorRng.Address & "=A" & i & ")*(MONTH(" & DateRng.Address & ")))>0,1))>3,""Selected"","""")"
Next i
End Sub
VBA-Only Solution
While completely disregarding your original code, you may be able to get inspired by this take on a VBA-only solution
Sub MarkColors()
Dim MstrSht As Worksheet
Dim DataArr As Variant
Dim ColorArr As Variant
Dim MonthCol As Collection
Dim CloseToDate As Date
Dim MaxDate As Date
Dim c As Long
Dim i As Long
Set MstrSht = ThisWorkbook.Sheets("masterfile")
'Define date
CloseToDate = DateSerial(2016, 6, 6) '<~~ Define date
'Load Data into Array
DataArr = MstrSht.Range("A2:C" & MstrSht.Cells(Rows.Count, 1).End(xlUp).Row)
'Find distinct colors
ColorArr = ReturnDistinct(MstrSht.Range("A2:A" & MstrSht.Cells(Rows.Count, 1).End(xlUp).Row))
'Remove any values in the arrays third column
For i = LBound(DataArr, 1) To UBound(DataArr, 1)
DataArr(i, 3) = ""
Next i
'Loop Each Color
For c = LBound(ColorArr) To UBound(ColorArr)
Set MonthCol = New Collection
MaxDate = 0
For i = LBound(DataArr, 1) To UBound(DataArr, 1)
If DataArr(i, 1) = ColorArr(c) Then
'Load the colors months into a collection
On Error Resume Next
MonthCol.Add Month(DataArr(i, 2)), CStr(Month(DataArr(i, 2)))
On Error GoTo 0
'Find Max Date
If DataArr(i, 2) <= CloseToDate Then
MaxDate = Application.WorksheetFunction.Max(MaxDate, DataArr(i, 2))
End If
End If
Next i
'If the color were found in three or more seperate months then the row with date closest to CloseToDate gets flagged
If MonthCol.Count > 2 Then
For i = LBound(DataArr, 1) To UBound(DataArr, 1)
If DataArr(i, 1) = ColorArr(c) And DataArr(i, 2) = MaxDate Then
DataArr(i, 3) = "Selected"
End If
Next i
End If
Next c
'Print results to sheet
MstrSht.Range("A2:C" & MstrSht.Cells(Rows.Count, 1).End(xlUp).Row) = DataArr
End Sub
'Return Array With Distinct Values
Function ReturnDistinct(InpRng As Range) As Variant
Dim Cell As Range
Dim i As Integer
Dim DistCol As New Collection
Dim DistArr()
'Add all values to collection
For Each Cell In InpRng
On Error Resume Next
DistCol.Add Cell.Value, CStr(Cell.Value)
On Error GoTo 0
Next Cell
'Write collection to array
ReDim DistArr(1 To DistCol.Count)
For i = 1 To DistCol.Count Step 1
DistArr(i) = DistCol.Item(i)
Next i
ReturnDistinct = DistArr
End Function
Note, that I am unsure about exactly which date you want to be the "selected" date. Thus, I have added the variable CloseToDate, and the code will "select" the row with the date that is closest (but smaller) than this particular date.
I have this sub in Excel 2010 that transfers columns from other sheets and inserts it into a table. The new table has 7 columns. The first 5 are just copying right from the other sheets and they work fine. The last two, however, are supposed match the Program Number from the new table against the Program Number in one of two other sheets and copy the column from there. These are the two that don’t work. It doesn’t throw any errors, the columns just don’t populate.
This is the excerpt that isn’t working. I’m quite new to VBA in excel so any assistance would be greatly appreciated.
Sub Program_List()
Dim SiteNoTransfer As String
Dim SiteNo As String
Dim TransferCol(7) As Integer
Dim Row As Integer
Dim RowTransfer As Integer
Dim StartColumn As Integer
Dim rSrc As Range
Dim rDst As Range
TransferCol(0) = 0 'Nothing (placeholder)
TransferCol(1) = 10 'Proj No, from Data
TransferCol(2) = 1
TransferCol(3) = 3
TransferCol(4) = 11
TransferCol(5) = 15
TransferCol(6) = 10 'From Sheet 1 or 2
TransferCol(7) = 17 'From Sheet 1 or 2
StartColumn = 45
Row = 7
Do While True
SiteNo = Worksheets("RESULTS").Cells(Row, StartColumn - 11)
If SiteNo = "" Then
Exit Do
ElseIf Not SiteNo = "" Then
RowTransfer = 4
Do While True
SiteNoTransfer = Worksheets("Data").Cells(RowTransfer, TransferCol(1))
If SiteNoTransfer = "END" Then
Exit Do
ElseIf SiteNoTransfer = SiteNo Then
Worksheets("RESULTS").Cells(Row, StartColumn + 1).Interior.Color = RGB(0, 255, 255)
Worksheets("Data").Cells(RowTransfer, TransferCol(1)).Interior.Color = RGB(0, 100, 255)
For i = 1 To 4
If Not TransferCol(i) = 0 Then
Worksheets("RESULTS").Cells(Row, StartColumn + i) = Worksheets("Program").Cells(RowTransfer, TransferCol(i))
End If
Next
For i = 5 To 5
If Not TransferCol(5) = 0 Then
Set rSrc = Sheets("Data").Cells(RowTransfer, TransferCol(5))
Set rDst = Sheets("RESULTS").Cells(Row, StartColumn + i)
rDst = rSrc
rDst.NumberFormat = "yyyy"
Exit Do
End If
Next
'Where the code stops
For i = 6 To 6
If Not TransferCol(6) = 0 Then
If Worksheets("RESULTS").Cells(Row, StartColumn + 1) = Worksheets("Sheet1").Cells(Row, TransferCol(1)) Then
Worksheets("RESULTS").Cells(Row, StartColumn + i) = Worksheets("Sheet1").Cells(RowTransfer, TransferCol(6))
End If
ElseIf Worksheets("RESULTS").Cells(Row, StartColumn + 1) = Worksheets("Sheet 2").Cells(Row, TransferCol(1)) Then
Worksheets("RESULTS").Cells(Row, StartColumn + i) = Worksheets("Sheet 2").Cells(RowTransfer, TransferCol(6))
End If
Next
For i = 7 To 7
If Not TransferCol(7) = 0 Then
If Worksheets("RESULTS").Cells(Row, StartColumn + 1) = Worksheets("Sheet 1").Cells(Row, TransferCol(1)) Then
Worksheets("RESULTS").Cells(Row, StartColumn + i) = Worksheets("Sheet 1").Cells(RowTransfer, TransferCol(7))
End If
ElseIf Worksheets("RESULTS").Cells(Row, StartColumn + 1) = Worksheets("Sheet 2").Cells(Row, TransferCol(1)) Then
Worksheets("RESULTS").Cells(Row, StartColumn + i) = Worksheets("Sheet 2").Cells(RowTransfer, TransferCol(7))
End If
Next
End If
RowTransfer = RowTransfer + 1
Loop
End If
Row = Row + 1
Loop
End Sub
EDIT: This is about what the sheets look like.
Sheet 1
| Project No. | Col 2 |... | Col 6 | Col 7
+------------+---------+-------+---------+
| 12-3456 | Date|... | 1234| 0987
+------------+---------+-------+---------+
| 22-3456 |Date|...| 2234 | 9876
+------------+---------+-------+---------+
Sheet 2
| Project No. | Col 2 |... | Col 6| Col 7
+------------+---------+-------+---------+-------------
| 32-3456 | Date |... | 3234 | 8765
+------------+---------+-------+---------+------------+
Results
| Project No. | Col 2 |... | Col 6 | Col 7
+------------+---------+-------+---------+-------------
| 12-3456 | Date |... | 1234 | 0987
+------------+---------+-------+---------+------------+
| 22-3456 | Date |... | 2324 | 9876
+------------+---------+-------+---------+------------+
| 32-3456 | Date |... | 3234 | 8765
So to clarify, in case this is still messy, if the Project Number matches Sheet1, then it takes column 6 from Sheet1, and the same for column 7.
I wound up doing this with VLOOKUP. So it looked something like:
=IFERROR(IFERROR(VLOOKUP(RC,'GROUP1'!A:O,6, FALSE),VLOOKUP(RC,'GROUP2'!A:O,6, FALSE),"")
Much clearer now and thanks for posting the columns. It appears as if though your If statement is returning "False" value and that's why the column is not populating.
However, I think you will need to post more of your code as it is currently not possible to debug it without knowing the values of Row, StartColumn, & RowTransfer.
But your code aside for a second, let me see if I understand correctly:
You check if the "Project Number" in A2 of the results sheet is matching the "Project Number" of A2 in Sheet1. If not then you check A3, A4, A5 of Sheet1 until you find a match.
If no match is found you start looking the same way in Sheet2.
Once the match is found, let say in A5 of Sheet1, you take the values of Columns 2-7 of the corresponding row in Sheet1 and copy them to the row with the same "Project Number" in the results sheet.
Please confirm if I understand you correctly so maybe a I can try and put together a code. Also, it would be helpful if you explain what is the reason for having 2 sheets (Sheet1 & Sheet2) as opposed to having just 1.
So i have a matrix formatted as so:
| | joe | michelle | tom |
|:-----: |:---: |:--------: |:---: |
| red | 1 | 0 | 1 |
| blue | 0 | 1 | 0 |
| green | 0 | 0 | 0 |
I'm trying to write VBA in excel to create two columns based on this table. If the cell inside the matrix is equal to "1", then I want to write the column name and row name into a list. So for example, because row "red" has a "1" in columns "joe" and "tom", and row "blue" has a "1" under "michelle", my new table would be like this:
| joe | red |
| tom | red |
| michelle | blue |
Here is the VBA i wrote so far, but it doesn't work and i hit a road block.
sub subname()
dim i as integer
for i = 1 to 3
if cells(2,i).value=1 then
cell(5,i).value = cells(1,i).value
end if
next i
end sub
You have only one cycle ...
Dim x As Integer
Range("B19").Select
x = 4
For i = 1 To 3 ' Row
For e = 1 To 3 ' Column
If ActiveCell.Offset(i, e).Value = "1" Then
x = x + 1
ActiveCell.Offset(x, 0).Value = ActiveCell.Offset(0, e).Value
ActiveCell.Offset(x, 1).Value = ActiveCell.Offset(i, 0).Value
End If
Next
Next
I consider B19 the top_left corner of the table ...
Ok the correct code is:
Dim i As Integer
For i = 1 To 3
If Cells(2, i + 1).Value = 1 Then
Cells(5, 1).Value = Cells(1, i + 1).Value
End If
Next i
If the top_left of the table is A1 The error is the reference of i. You need to add 1 or change the cycle from 2 to 4.The second "error" it's to put the value in cell(5,i) instead of cells(5,1). In that case you have to put the name in a fix position. In a cycle you change in Cells(5+e,1)...
You can use this code also.
Sub prabhat()
Dim rng As Range
Dim r As Integer
Dim c As Integer
Dim lastRow As Integer
Dim lastRow2 As Integer
Set rng = Range("a2:d4")
For Each dng In rng
lastRow = Range("E" & Rows.Count).End(xlUp).Row
lastRow2 = Range("F" & Rows.Count).End(xlUp).Row
If dng.Value = 1 Then
r = dng.Row
c = dng.Column
Range("E" & lastRow + 1).Value = Cells(r, 1).Value
Range("F" & lastRow2 + 1).Value = Cells(1, c).Value
End If
Next dng
End Sub