I wish to have a VBA macro that will help me to edit values in the column 'C' for each row until the sum value has reached.
However, there are some criteria:
The value has to be smaller than the value in column 'B'
If the value in column 'B' is zero, then the value in column 'C' should be zero
For example:
I have certain values in column A for each row and I want the sum for Column C to be 10. Hence, the VBA will loop and iterate each row in column C and check if the number in Column B is greater than 0, if yes then it will add 1 to it. After going through each row, it will check the sum, if the sum has not reach the certain amount (in this case, it's 10), it will loop back again and add 1 to each row and stop when it reaches the sum.
Example output:
----------------------
Column B | Column C
----------------------
124 | 3
100 | 3
83 | 2
23 | 1
4 | 1
0 | 0
-----------------------
Code:
Sub Loop()
Dim Report As Worksheet
Set Report = Excel.ActiveSheet
Dim cell As Range
Dim i As Integer
Dim total As Integer
total = Range("C8").Value
Range("C2:C7").ClearContents
For total = 0 To 10
For Each cell In Range("C2:C12")
For i = 2 To 7
If Range("B" & i).Value > 0 Then
cell.Value = cell.Value + 1
If cell.Value > Range("B" & i).Value Then
cell.Value = cell.Value
End If
Else:
cell.Value = 0
End If
Next i
Next cell
total = total + Range("C8").Value
Next total
End Sub
However, the output that I got seems to be not my desire output and I got all zeros instead. I am a newbie to VBA :(, can anyone help me with this?
Below is my take on your problem but a couple of things to start...
VBA didn't much like the sub having the name loop as loop is a reserved word
I've used methods intersect and offset when working with ranges but there are multiple ways to skin this cat
Range("C2:C7").ClearContents will result in empty cells and while an empty cell will likely be considered 0 when trying to add 1 to the value, it would perhaps be better to give the cells an explicit value e.g. 0
There exists some cases where a total of, for example, 10 can't be reached and if not tested for and handled, the loop will run forever, never reaching 10
I'm not sure if msgbox is appropriate to your task but I popped it in anyway in case you haven't yet come across it
Sub SomeLoop()
Set totalCell = Range("C8")
Set editableColumnRange = Range("C2:C7")
'set all the editable cells to a default/initial value
editableColumnRange.Value = 0
totalAtEndOfLastLoop = 0
total = 0
Offset = 0
Do While total < 10
'set the current row to the current row offset past the top row of the editable cells
Set currentRowRange = editableColumnRange.Rows(1).EntireRow.Offset(Offset)
Set currentCCell = Intersect(currentRowRange, Range("C:C"))
Set currentBCell = Intersect(currentRowRange, Range("B:B"))
'implement the rules
If currentBCell.Value = 0 Then
currentCCell.Value = 0
ElseIf currentBCell.Value > currentCCell.Value + 1 Then
'to ensure b remains > c, we need to test b > c + 1
'so if c is incremented by 1, it remains less than b
currentCCell.Value = currentCCell.Value + 1
total = total + 1
End If
Offset = Offset + 1
If Offset >= editableColumnRange.Rows.Count Then
'we've got an offset which would task us past the data
'it's time to wrap around
'check if the total has changed otherwise we'll be stuck in the loop forever
If total > totalAtEndOfLastLoop Then
totalAtEndOfLastLoop = total
Offset = 0
Else
MsgBox "The total hasn't changed"
Exit Do
End If
End If
Loop
End Sub
Increment While Less Than
Adjust the values in the constants section and the worksheets (possibly workbooks).
Option Explicit
Sub doIncrement()
' Constants
Const sFirst As String = "B2"
Const dFirst As String = "C2"
Const iTotal As Long = 10
' Worksheets (could be different)
Dim sws As Worksheet: Set sws = ActiveSheet
Dim dws As Worksheet: Set dws = ActiveSheet
' Create a reference to the Source Range.
Dim srg As Range
With sws.Range(sFirst)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Sub
Set srg = .Resize(lCell.Row - .Row + 1)
End With
' Write values from Source Range to Source Array.
Dim rCount As Long: rCount = srg.Rows.Count
Dim sData As Variant
If rCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData = srg.Value
Else
sData = srg.Value
End If
' Define Destination Array.
Dim dData() As Long: ReDim dData(1 To rCount, 1 To 1) ' Long: all zeros
Dim r As Long
Dim dTotal As Long
' Loop through rows of Source Array and write to rows of Destination Array.
Do
For r = 1 To rCount
If sData(r, 1) - dData(r, 1) > 1 Then
dData(r, 1) = dData(r, 1) + 1
dTotal = dTotal + 1
If dTotal = iTotal Then
Exit Do
End If
End If
Next r
Loop
With dws.Range(dFirst)
' Write values from Destination Array to Destination Range.
.Resize(rCount).Value = dData
' Clear contents below.
.Resize(.Worksheet.Rows.Count - .Row - rCount + 1) _
.Offset(rCount).ClearContents
End With
End Sub
Related
hello i worte a funnction that sums ahe abslute diffrence betwen two cells each time and then i subtact 70000 from the sum
i would like to to this in vba more aesthetic
70000-(IF(D2>0,ABS(D2-C2))+IF(E2>0,ABS(E2-D2))+IF(F2>0,ABS(F2-E2))+IF(G2>0,ABS(G2-F2))+IF(H2>0,ABS(H2-G2))+IF(I2>0,ABS(I2-H2))+IF(J2>0,ABS(J2-I2))+IF(K2>0,ABS(K2-J2))+IF(L2>0,ABS(L2-K2))+IF(M2>0,ABS(M2-L2))+IF(N2>0,ABS(N2-M2))+IF(O2>0,ABS(O2-N2)) )
Why not simply:
=70000-SUMPRODUCT(ABS(D2:O2-C2:N2),N(D2:O2>0))
Maybe a bit off-topic since you specifically ask for a VBA solution, but this formula-solution would also bring aesthetic and improves calculation:
=70000-
REDUCE(0, COLUMN(C:N),
LAMBDA(a, b,
LET(offset,INDEX(2:2,,b+1),
IF(offset>0,
a+ABS(offset-INDEX(2:2,,b)),
a))))
It loops through column C:N (b) in the row mentioned (row 2:2 in this case) and checks if the value offset 1 to the right (I used INDEX to not make it volatile, but named it offset).
If the value in that row/column+1 is greater than 0 than value a becomes a + ABS(the value in the row/column+1 - value in that row/column), otherwise a stays the same.
Edit:
For if your range might grow/decrease this may be a nice dynamic solution:
=70000-LET(range,C2:Z2,
cols,DROP(FILTER(COLUMN(range),range<>""),,-1),
REDUCE(0,cols,LAMBDA(a,b,LET(offset,INDEX(2:2,,b+1),IF(offset>0,a+ABS(offset-INDEX(2:2,,b)),a)))))
It checks for any values in the range C2:Z2 (Z could be expanded) and filters out the blanks.
Than it takes all columns in the range minus the last (for the offset calculation purpose).
Note that if there are gaps in your data this would filter those out as well.
First, based on your formula, you rather only add the absolute difference if the value subtracted from is >0. If this is what you want, then you would have something like this:
Sub SumAbsDiff()
Dim i As Integer
Dim sum As Double
'This loops from col D to col O
For i = 4 To 15 Step 1
If Cells(2, i).Value > 0 Then sum = sum + Abs(Cells(2, i).Value - Cells(2, i - 1).Value)
Next i
'Change this to the cell you would like to display the value
Cells(1, 1).Value = 70000 - sum
End Sub
Explanation:
Here, we are taking row 2, and then looping over from D until O. Using the loop, we absolute subtract each of them (D-C, E-D, etc) if the >0 condition satisfy. The result is then add to the sum variable (which initialize as 0 by default).
After the loop is done, we just simply use it to subtract from 70,000 and then write it to the cell that we wanted.
As a side note, if your original formula was wrong, and you actually want the sum between each of the absolute differences without the >0 condition, then removing the If ... Then would do the trick.
Sum Up Absolute Differences
Static (C2:O2)
Sub SumUpAbsStatic()
Const SRC_NAME As String = "Sheet1"
Const SRC_RANGE As String = "C2:O2"
Const DST_CELL As String = "B2"
Const INIT_VALUE As Double = 70000
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Sheets(SRC_NAME)
Dim Data(): Data = ws.Range(SRC_RANGE).Value
Dim pValue: pValue = Data(1, 1)
Dim cValue, c As Long, Total As Double
For c = 2 To UBound(Data, 2)
cValue = Data(1, c)
If IsNumeric(pValue) Then
If IsNumeric(cValue) Then
If cValue > 0 Then Total = Total + Abs(cValue - pValue)
End If
End If
pValue = cValue
Next c
Total = INIT_VALUE - Total
ws.Range(DST_CELL).Value = Total
End Sub
Dynamic (C2:LastColumn2)
Sub SumUpAbsolute()
Const SRC_NAME As String = "Sheet1"
Const SRC_FIRST_CELL As String = "C2"
Const DST_CELL As String = "B2"
Const INIT_VALUE As Double = 70000
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Sheets(SRC_NAME)
Dim srg As Range, cCount As Long
With ws.Range(SRC_FIRST_CELL)
Dim lCell As Range: Set lCell = .Resize(, ws.Columns.Count _
- .Column + 1).Find("*", , xlFormulas, , , xlPrevious)
If Not lCell Is Nothing Then
cCount = lCell.Column - .Column + 1
Set srg = .Resize(, cCount)
End If
End With
Dim Total As Double
If cCount > 1 Then
Dim Data(): Data = srg.Value
Dim pValue: pValue = Data(1, 1)
Dim cValue, c As Long
For c = 2 To cCount
cValue = Data(1, c)
If IsNumeric(pValue) Then
If IsNumeric(cValue) Then
If cValue > 0 Then Total = Total + Abs(cValue - pValue)
End If
End If
pValue = cValue
Next c
End If
Total = INIT_VALUE - Total
ws.Range(DST_CELL).Value = Total
End Sub
You can achieve this in VBA using a for loop:
Sub AbsoluteDifference(n As Double, startCell As String, outputCell As String)
' Store variables as double to account for large numbers and decimals
Dim sum As Double
sum = 0
'Range until the last filled cell
For Each i In Range(startCell, Range(startCell).End(xlToRight)).Cells
If i.Value > 0 Then
sum = sum + Abs(i.Value - i.Offset(0, -1).Value)
End If
Next i
' Save the value to outputCell
Range(outputCell).Value = n - sum
End Sub
' Run the Main sub to call AbsoluteDifference with parameters
Sub Main()
Call AbsoluteDifference(70000, "D2", "C3")
End Sub
This code produces an identical result to your function.
I am looking to count the occurrences of consecutive numbers in a column and cannot seem to find a logical way to calculate this within a loop.
My column of values is simply entries of 0 or 1. What I want to is count each time there is two 0's in a row, three 0's a row, four 0's in a row and so on. The maximum number of times I would expect a consecutive number is 15.
Ideally, I would like the output for each occurrence entered into a table.
I have provided a snapshot below of the column in question.
My attempts so far consist of looping through the column checking for two 0's in a row, starting at row 2 but this causes issues when I have more than two 0's in a row.
'Check for 2
Dim TwoCount, RowNo As Integer, LastRow As Long
LastRow = Sheets("Data").Range("A165536").End(xlUp).Row
TwoCount = 0
RowNo = 2
For i = 2 To LastRow
If Sheets("Data").Range("H" & RowNo).Value = 1 Then
RowNo = RowNo + 1
Else
If Sheets("Data").Range("H" & RowNo).Value = 0 Then
TwoCount = 1
RowNo = RowNo + 1
If Sheets("Data").Range("H" & RowNo).Value = 0 Then
TwoCount = 2
RowNo = RowNo + 1
If Sheets("Data").Range("H" & RowNo).Value = 1 Then
End If
End If
End If
End If
Next i
I welcome any suggestions to how I should approach this? Whether it's easier as a formula or array formula.
Desired output
Count Consecutive Occurrences
Option Explicit
Sub CountConsecutive()
' Source
Const sName As String = "Data"
Const sFirstCellAddress As String = "H1"
Const sCriteria As Variant = 0
' Destination
Const dName As String = "Data"
Const dFirstCellAddress As String = "J1"
Dim dHeaders As Variant
dHeaders = VBA.Array("Occurrences", "Number of Times")
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Write the values from the source column to an array.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim Data As Variant
Dim rCount As Long
With sws.Range(sFirstCellAddress)
Dim slCell As Range: Set slCell = .Resize(sws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If slCell Is Nothing Then Exit Sub
rCount = slCell.Row - .Row + 1
If rCount < 2 Then Exit Sub
Data = .Resize(rCount).Value
End With
' Count the occurrences by using a dictionary.
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim Key As Long
Dim r As Long
Dim cCount As Long
Dim MaxCount As Long
For r = 2 To rCount
Key = Data(r, 1)
If IsNumeric(Key) Then
If Key = sCriteria Then
cCount = cCount + 1
Else
If cCount > 0 Then
dict(cCount) = dict(cCount) + 1
If cCount > MaxCount Then MaxCount = cCount
cCount = 0
End If
End If
End If
Next r
If MaxCount = 0 Then Exit Sub
' Write the values from the dictionary to the array.
rCount = MaxCount + 1
ReDim Data(1 To rCount, 1 To 2)
Data(1, 1) = dHeaders(0)
Data(1, 2) = dHeaders(1)
For r = 2 To rCount
Data(r, 1) = r - 1
If dict.Exists(r - 1) Then
Data(r, 2) = dict(r - 1)
Else
Data(r, 2) = 0
End If
Next r
' Write the values from the array to the destination range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
With dws.Range(dFirstCellAddress).Resize(, 2)
.Resize(rCount).Value = Data
.Resize(dws.Rows.Count - .Row - rCount + 1).Offset(rCount).Clear
'.Font.Bold = True
'.EntireColumn.AutoFit
End With
'wb.save
MsgBox "Consecutive count created.", vbInformation
End Sub
COUNTING THE FREQUENCY OF CONSECUTIVE OCCURRENCES OF 0 IN A COLUMN
You may try this array formula as well,
• Formula used in cell L2
=SUMPRODUCT(--(FREQUENCY(
IF($H$2:$H$32=0,ROW($H$2:$H$32)),
IF($H$2:$H$32=1,ROW($H$2:$H$32)))=K2))
And Fill Down!
Note: Array formulas need to be entered by pressing CTRL + SHIFT + ENTER (not just ENTER). Hold down both the CTRL key and the SHIFT key then hit ENTER. If you are using Excel 2021 or O365 you can only press ENTER.
Imagine your numbers Win/Lose in column A then add in cell B3 (not B2 this will stay empty) the following formula and copy it down:
=IF(AND(A3=0,A3<>A4),COUNTIF($A$2:A3,A3)-SUM($B$2:B2),"")
Then to count them just use =COUNTIF(B:B,E2) in F2 and copy it down.
You can read this requirements in two ways as I see it:
You can count an occurence of 1,2,3 and 4 in a sequence of 4 zero's;
You can count only the max occurence of the above;
I went with the assumptions of the latter:
Formula in C1:
=LET(X,SEQUENCE(15),Y,LEN(TEXTSPLIT(CONCAT(IF(A2:A32," ",1)),," ",1)),VSTACK({"Occurences of 0","Number of Times"},HSTACK(X,BYROW(X,LAMBDA(a,SUM(--(Y=a)))))))
Important note:
It may not be best to rely on CONCAT() since depending on the amount of rows you want to concatenate, it may strike a character limit. Instead you could try something like:
=LET(X,SEQUENCE(15),Y,LEN(TEXTSPLIT(REDUCE("",A2:A32,LAMBDA(a,b,a&IF(b," ",1))),," ",1)),VSTACK({"Occurences of 0","Number of Times"},HSTACK(X,BYROW(X,LAMBDA(a,SUM(--(Y=a)))))))
Also, please note that ms365 is required for the above functions to run properly (and at time of writing VSTACK(), HSTACK() and TEXTSPLIT() are still in the insider's BETA-channels.
I have code that will clear everything below the "----" on a spreadsheet full of data. The "----"comes from an export into excel and I don't want data located under it, so I clear it.
After the code clears everything underneath the "----", I want to sum each column in a range and then place each column total underneath its column of data. The column range is F thru T. I'd like to be able to change this range in the code for other projects.
The row may not be the same each time, so the code must sum the columns after the last row of data.
Can anyone help with this, thanks!
Sub Remove_everything_under()
Dim mtch As Long
mtch = 0
On Error Resume Next
mtch = Application.WorksheetFunction.Match("----", ActiveSheet.Range("A:A"), 0) + 0
On Error GoTo 0
If mtch > 0 Then
ActiveSheet.Range("A" & mtch, ActiveSheet.cells(Rows.Count, Columns.Count)).ClearContents
End If
End Sub
Sum-up Variable Sized Column Ranges
Description
Adjust the values in the constants section.
You can easily rewrite the procedure to use some of the constants as arguments for multi-purpose use.
The following will sum up the columns defined by cAddress and put the results (sums) to the cells below each non-empty column range. Executing it again will double the previous result each next time.
Some Challenges
Sum will fail if an error value so the cells of the column range have to be looped through. Solved.
Sum will sum up date values. Not solved, but not an issue when looping.
The loop will sum up TRUE as -1. Solved, but not an issue when Sum is used.
Option Explicit
Sub sumupVariableSizedColumnRanges()
Const cAddress As String = "F:T" ' Columns Address
Const FirstRow As Long = 2 ' First Row
Const hasDates_Slow As Boolean = True ' If 'True', then loop always.
Dim frOffset As Long: frOffset = FirstRow - 1 ' First Row Offset
Dim rg As Range ' Initial Range: from FirstRow to last worksheet row.
With ActiveSheet.Columns(cAddress)
Set rg = .Resize(.Rows.Count - frOffset).Offset(frOffset)
'Debug.Print "Initial Range address = " & rg.Address(0, 0)
End With
Dim crg As Range ' Column Range
Dim rrg As Range ' Result Range
Dim lCell As Range ' Last Cell (Range)
Dim cError As Long ' Current Error Number
Dim Result As Double ' Result
' If error, then loop.
Dim Data As Variant ' Data Array
Dim cValue As Variant ' Current Value
Dim r As Long ' Data Array Rows Counter
' Starting idea if same last row for all columns:
' Set lCell = rg.Find("*", , xlFormulas, , xlByRows, xlPrevious)
' If lCell Is Nothing Then Exit Sub
' Set rg = rg.Resize(lCell.Row - frOffset)
' Debug.Print "Processing Range address = " & rg.Address(0, 0)
For Each crg In rg.Columns
Set lCell = crg.Find("*", , xlFormulas, , , xlPrevious)
If Not lCell Is Nothing Then
Set rrg = crg.Resize(lCell.Row - frOffset)
'Debug.Print "Current Range address = " & rrg.Address(0, 0)
If hasDates_Slow Then
cError = -1 ' Dates are not summed up.
Else
On Error Resume Next ' Sum 'fails' if error values.
Result = Application.Sum(rrg) ' Dates are also summed up.
cError = Err.Number
On Error GoTo 0
End If
If cError <> 0 Then
'Debug.Print "Current Error Number = " & cError
cError = 0
Result = 0
If rrg.Rows.Count = 1 Then
ReDim Data(1 To 1, 1 To 1): Data = rrg.Value
Else
Data = rrg.Value
End If
For r = 1 To UBound(Data, 1)
cValue = Data(r, 1)
If IsNumeric(cValue) Then
If VarType(cValue) <> vbBoolean Then ' exclude TRUE = -1
Result = Result + cValue
End If
End If
Next r
Erase Data
End If
lCell.Offset(1).Value = Result
Set lCell = Nothing
End If
Next crg
End Sub
At a high level I am trying to set a cell equal to a random cell within a range. The issue I am having is that in this range I want to pull a random Value from, the Value I am taking is the result of an 'if' expression that either sets the cell to a Value or "". So when I chose the random value I only want to choose cells that have an actual value, not the "".
Does anyone know how to get this expected behavior?
The code below shows what I have tried currently, each large block is commented to help with understanding. The block I need help with replaces the values in each column until the next cell is blank then moves to the next column.
upperBound = 1798
lowerBound = 2
Randomize
'This loop section populates the data area with a static value in cell 9,3 then 9,4 etc..
For j = 3 To 15
val = Cells(9, j).Value
For i = 1 To val
Cells(12 + i, j).Value = Cells(9, j)
Next i
Next j
'This loop section uses the cells already populated down each column and replaces that value with the random value from the other range
Dim x As Integer
' Set numrows = number of rows of data.
For j = 3 To 15
NumRows = Range(Cells(13, j), Cells(13, j).End(xlDown)).Rows.Count
' Select cell 13,j.
Cells(13, j).Select
' Establish "For" loop to loop "numrows" number of times.
For x = 1 To NumRows
ActiveCell.Value = Worksheets("2017 Role IDs").Cells(Int((upperBound - lowerBound + 1) * Rnd + lowerBound), 2).Value
' Selects cell down 1 row from active cell.
ActiveCell.Offset(1, 0).Select
Next
Next j
This is the data before the second block runs. I want to replace the values that just match the number in the second row with the random number in the range:
This is what I would like to look like:
But currently it looks like this because the random selector is taking blank values:
Something like this should work for you:
Sub tgr()
Dim wb As Workbook
Dim wsNums As Worksheet
Dim wsDest As Worksheet
Dim aData As Variant
Dim vData As Variant
Dim aNums() As Double
Dim aResults() As Variant
Dim lNumCount As Long
Dim lMaxRows As Long
Dim lRowCount As Long
Dim ixNum As Long
Dim ixResult As Long
Dim ixCol As Long
Set wb = ActiveWorkbook
Set wsNums = wb.Worksheets("2017 Role IDs")
Set wsDest = wb.ActiveSheet
With wsNums.Range("B2", wsNums.Cells(wsNums.Rows.Count, "B").End(xlUp))
If .Row < 2 Then Exit Sub 'No data
lNumCount = WorksheetFunction.Count(.Cells)
If lNumCount = 0 Then Exit Sub 'No numbers
ReDim aNums(1 To lNumCount)
If .Cells.Count = 1 Then
ReDim aData(1 To 1, 1 To 1)
aData(1, 1) = .Value
Else
aData = .Value
End If
'Load populated numeric cells into the aNums array
For Each vData In aData
If Len(vData) > 0 And IsNumeric(vData) Then
ixNum = ixNum + 1
aNums(ixNum) = vData
End If
Next vData
End With
lMaxRows = Application.Max(wsDest.Range("C9:O9"))
If lMaxRows = 0 Then Exit Sub 'Row count not populated in row 9 for each column
ReDim aResults(1 To WorksheetFunction.Max(wsDest.Range("C9:O9")), 1 To 13)
'Populate each column accordingly and pull a random number from aNums
For ixCol = 1 To UBound(aResults, 2)
If IsNumeric(wsDest.Cells(9, ixCol + 2).Value) Then
For ixResult = 1 To CLng(wsDest.Cells(9, ixCol + 2).Value)
Randomize
aResults(ixResult, ixCol) = aNums(Int(Rnd() * lNumCount) + 1)
Next ixResult
End If
Next ixCol
wsDest.Range("C13").Resize(UBound(aResults, 1), UBound(aResults, 2)).Value = aResults
End Sub
Having issues with some vba, if anyone can point me in the right direction it would be greatly appreciated, currently my code is returning a full row of data and it is returning multiple rows, this is my current code.
Sub BUTTONtest_Click()
Dim c As Range
Dim j As Integer
Dim Source As Worksheet
Dim Target As Worksheet
' Change worksheet designations as needed
Set Source = ActiveWorkbook.Worksheets("Two Years")
Set Target = ActiveWorkbook.Worksheets("Two Years League")
j = 3 ' Start copying to row 1 in target sheet
For Each c In Source.Range("G6:K6") ' Do 50 rows
If c.Text = "OVER" Then
Source.Rows(c.Row).Copy Target.Rows(j)
j = j + 1
End If
Next c
End Sub
I need to look at each row and in each row if the word "OVER" appears I need it to return the information in the side bar e.g. column B I would need this to apply for each wee section e.g. Column C- F should return the number from column B and H-K should return G etc.
This?
Sub BUTTONtest_Click()
Dim c As Range
Dim j As Integer
Dim Source As Worksheet
Dim Target As Worksheet
' Change worksheet designations as needed
Set Source = ActiveWorkbook.Worksheets("Two Years")
Set Target = ActiveWorkbook.Worksheets("Two Years League")
j = 3 ' Start copying to row 1 in target sheet
For i = 1 To 3 'Number of ¿wees?
For Each c In Source.Range(Cells(6, 5 * i - 2), Cells(50, 5 * i + 1)) ' Do 50 rows
If c.Text = "OVER" Then
Target.Cells(j, 1) = Source.Cells(c.Row, 5 * i - 3)
j = j + 1
End If
Next c
Next i
End Sub
EDIT
If don't want repeated rows, try this one:
Sub BUTTONtest_Click()
Dim c As Range
Dim j As Integer
Dim Source As Worksheet
Dim Target As Worksheet
' Change worksheet designations as needed
Set Source = ActiveWorkbook.Worksheets("Two Years")
Set Target = ActiveWorkbook.Worksheets("Two Years League")
j = 3 ' Start copying to row 1 in target sheet
a = 1
For i = 1 To 3 'Number of ¿wees?
For Each c In Source.Range(Cells(6, 5 * i - 2), Cells(50, 5 * i + 1)) ' Do 50 rows
If c.Text = "OVER" Then
If a <> c.Row Then
Target.Cells(j, 1) = Source.Cells(c.Row, 5 * i - 3)
j = j + 1
a = c.Row
End If
End If
Next c
Next i
End Sub
you could try this code (commented)
Option Explicit
Sub BUTTONtest_Click()
Dim Source As Worksheet
Dim Target As Worksheet
Dim iSection As Long
Dim sectionIniCol As Long, sectionEndCol As Long
' Change worksheet designations as needed
Set Source = ActiveWorkbook.Worksheets("Two Years")
Set Target = ActiveWorkbook.Worksheets("Two Years League")
With Source '<--| reference 'Source' sheet
With .Range("B6:F" & .Cells(.Rows.Count, "B").End(xlUp).row) '<--| reference its columns "B:F" range from row 6 down to last non empty cell in column "B"
With .Offset(, -1).Resize(, 1) '<--| reference corresponding cells in column "A" (which is an empty column)
For iSection = 1 To 3 '<-- loop over all your three 5-columns sections
sectionIniCol = (iSection - 1) * 5 + 2 '<-- evaluate current section initial col
sectionEndCol = sectionIniCol + 4 '<-- evaluate current section ending col
.FormulaR1C1 = "=if(countif(RC" & sectionIniCol + 1 & ":RC" & sectionEndCol & ",""OVER"")>0,1,"""")" '<-- write (temporary) formulas in column "A" cells to result "1" should at least one "OVER" occurrence be in corresponding cells of current section columns
If WorksheetFunction.Sum(.Cells) > 1 Then Intersect(.Columns(sectionIniCol), .SpecialCells(xlCellTypeFormulas, xlNumbers).EntireRow).Copy Target.Cells(Target.Rows.Count, 1).End(xlUp).Offset(1) '<-- if any occurrence of "OVER" has been found then copy section initial column cells corresponding to column "A" cells marked with "1" and paste them in from first empty row of 'Target' sheet...
Next iSection
.ClearContents '<--| delete (temporary) formulas in target column "A"
End With
End With
End With
End Sub