I have the following Excel spreadsheet:
col2 col3 col4 col5 col6
row2 2 0 1004 0 200
row3 0 0 0 0 0
row4 0 0 0 0 57
row5 1 22 67 11 303
row6 0 0 0 0 0
row7 1 2 3 4 5
row8 3 3 3 3 3
I would like to have printed or identified the names of the rows that have all zeros after them. For the above example, output should be:
row3
row6
as these are the names of the only rows with all zeros after the first (name) cell.
Below is code of how I think these names (subset of column 1) could be found.
// Setting the variables for the above example
common_char = 0
num_rows = 8;
num_columns = 6;
boolean show = true;
for x in range (2 , num_rows):
for y in range (2 , num_columns):
if (cell[x,y] != common_char):
show = false
if (show == true):
print cell[x,1]
show = true
end
How should I implement this with Excel?
Thank you for your assistance.
Try
Option Explicit
Public Sub Test()
Dim common_char As Long, num_rows As Long, num_Columns As Long, iRow As Range, loopRange As Range
common_char = 0
num_rows = 7 '8
num_Columns = 5 '6
With ActiveSheet
Set loopRange = .Cells(2, 2).Resize(num_rows, num_Columns)
For Each iRow In loopRange.Rows
If Application.WorksheetFunction.CountIf(iRow, common_char) = num_Columns Then
MsgBox iRow.Address
End If
Next iRow
End With
End Sub
This works for data laid out as follows, therefore I have removed 1 from both num_rows and num_columns to account for actual data range.
Related
I am trying to write a macro using VBA in excel to copy the rows based on column A that does not appear in column B, to a new sheet. For example, on the following table, only copy the rows with column A that is 3,4, 5, and 6 to a new sheet. Any help is greatly appreciated.
The table looks like below.
Column A ColumnB
1 1
1 2
1 7
2 -
2 -
3 -
3 -
4 -
5 -
5 -
6 -
7 -
Sub sorter()
Dim find1 As Object, find2 As Object
Dim row1 As Integer, row2 As Integer
Dim myWB As Workbook
Set myWB = ThisWorkbook
row1 = 1
row2 = 1
Do
Set find1 = myWB.Sheets(1).Range("B:B").Find(What:=myWB.Sheets(1).Cells(row1, 1).Value, LookIn:=xlValues)
If find1 Is Nothing Then
Set find2 = myWB.Sheets(2).Range("A:A").Find(What:=myWB.Sheets(1).Cells(row1, 1).Value, LookIn:=xlValues)
If find2 Is Nothing Then
myWB.Sheets(2).Cells(row2, 1).Value = myWB.Sheets(1).Cells(row1, 1).Value
row2 = row2 + 1
End If
End If
row1 = row1 + 1
Loop Until myWB.Sheets(1).Cells(row1, 1).Value = ""
End Sub
just make sure you dont put blanks in first column :)
I'm looking to highlight table cells with tracked changes.
Here is my VBA code:
Sub HiliteChanges()
Dim oTable As Table
Dim oColumn As Column
Dim oCell As Cell
Dim oRange As Range
Dim numRevs As Integer
Dim tableIndex, rowIndex, cellIndex As Integer
For tableIndex = 1 To ActiveDocument.Tables.Count
For rowIndex = 1 To ActiveDocument.Tables(tableIndex).Rows.Count
For cellIndex = 1 To ActiveDocument.Tables(tableIndex).Rows(rowIndex).Cells.Count
numRevs = ActiveDocument.Tables(tableIndex).Rows(rowIndex).Cells(cellIndex).Range.Revisions.Count
Debug.Print tableIndex, rowIndex, cellIndex, numRevs
If numRevs > 0 Then
ActiveDocument.Tables(tableIndex).Rows(rowIndex).Cells(cellIndex).Shading.BackgroundPatternColor = wdColorBlueGray
End If
Next
Next
Next
End Sub
What it ends up doing is highlighting the entire row, even if only one cell in a row is changed.
I made a change in a table with 3 rows and 6 columns. The change was in the fourth column of the first row. I turned off Track Changes prior to running the script. This was the output:
1 1 1 1
1 1 2 1
1 1 3 1
1 1 4 1
1 1 5 1
1 1 6 1
1 2 1 0
1 2 2 0
1 2 3 0
1 2 4 0
1 2 5 0
1 2 6 0
1 3 1 0
1 3 2 0
1 3 3 0
1 3 4 0
1 3 5 0
1 3 6 0
So it looks like every cell in the first row has a change, but it doesn't. There was only one cell with a change.
Is there a way to highlight only the cells that have changes? (Obviously my way is flawed in some way, but I can't see where.)
When you check for revisions, don't include the "end of cell" marker in the checked range. Don't ask me why that works...
Sub HiliteChanges()
Dim oTable As Table
Dim oColumn As Column, oRow As Row, rng As Range
Dim oCell As Cell
Dim oRange As Range
Dim numRevs As Integer
Dim tableIndex, rowIndex, cellIndex As Integer
For tableIndex = 1 To ActiveDocument.Tables.Count
Set oTable = ActiveDocument.Tables(tableIndex)
For rowIndex = 1 To oTable.Rows.Count
Set oRow = oTable.Rows(rowIndex)
For cellIndex = 1 To oRow.Cells.Count
Set oCell = oRow.Cells(cellIndex)
Set rng = oCell.Range
'don't include the "end of cell" marker in the checked range
rng.MoveEnd wdCharacter, -1
numRevs = rng.Revisions.Count
Debug.Print tableIndex, rowIndex, cellIndex, numRevs
If numRevs > 0 Then
oCell.Shading.BackgroundPatternColor = wdColorBlueGray
End If
Next
Next
Next
End Sub
I'm looking for a way for copying down all data found between a range and paste it in a next column.
A= text data
B= Random numbers but always starting from 1
C= some data
D= My needed solution
Example:
A B C D
018404.00 1 20 20
018404x0 2 0 20
018404f1 2 0 20
018404v1 3 0 20
11000-0532 4 0 20
1004-1101 5 0 20
0720-0125 3 0 20
0810-0001 3 0 20
0710-0040 3 0 20
052269.00 1 0 80
052269v6 2 0 80
11001-0000 3 0 80
1001-1110 4 0 80
0720-0500 2 0 80
0810-0001 2 80 80
0720-0002 2 0 80
052275.00 1 0 160
052275v2 2 160 160
When the value in column B is 1 then find value in column C (in Range B:B from 1 to 1) copying it to D
I have tried it with a formula but this limits the depth. If value on Column C isto far from the 1 row it doesn't work.
=IF(AND(B2=1;C2=0);IF(B3=1;0;IF(C3=0;IF(C4=0;C5;C4);C3));IF(C2>0;C2;I1))
So I think I need a vba solution.
i think you need something like this.
This code search max value between your 1 and 1 value
Sub FindValBetweenOne()
Dim LastRow As Long
Dim FindVal As Long
LastRow = Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
For I = 1 To LastRow
If Cells(I, "B").Value = 1 Then 'find next "1"
FindVal = Cells(I, "C").Value
J = I + 1
Do While (J <= LastRow And Cells(J, "B").Value <> 1)
If Cells(J, "C").Value > FindVal Then
FindVal = Cells(J, "C")
End If
J = J + 1
Loop
End If
Cells(I, "D").Value = FindVal
Next I
End Sub
I think what I'm trying to do is pretty basic, but I'm brand new to VBA so I'm getting stuck and the answers I've found are close, but not quite right.
I have a list of row entries, like this:
1 4 32 2 4
2 6 33 1 3
1 4 32 2 4
4 2 30 1 5
Notice that rows 1 and 3 are duplicates. I'd like to only have a single instance of each unique row but I don't want to just delete the duplicates, I want to report how many of each type there are. Each row represents an inventory item, so deleting duplicate entries without indicating total quantity would be very bad!
So, my desired output would look something like this, where the additional 6th column counts the total number of instances of each item:
1 4 32 2 4 2
2 6 33 1 3 1
4 2 30 1 5 1
My data sets are larger than just these 5 columns, they're closer to 10 or so, so I'd like to put that last column at the end, rather than to hardcode it to the 6th column (i.e., column "F")
Update:
I found some code that worked with minor tweaking, and it worked this morning, but after messing around with some other macros, when I came back to this one it was telling me that I have a "compile error, wrong number of arguments or invalid property assignment" and it seemed to be unhappy with the "range". Why would working code stop working?
Sub mcrCombineAndScrubDups2()
For Each a In range("A1", Cells(Rows.Count, "A").End(xlUp))
For r = 1 To Cells(Rows.Count, "A").End(xlUp).Row - a.Row
If a = a.Offset(r, 0) And a.Offset(0, 1) = a.Offset(r, 1) And a.Offset(0, 2) = a.Offset(r, 2) Then
a.Offset(0, 4) = a.Offset(0, 4) + a.Offset(r, 4)
a.Offset(r, 0).EntireRow.Delete
r = r - 1
End If
Next r
Next a
End Sub
Assuming that your data starts from A1 on a worksheet named ws1, the following code removes the duplicated rows. Not by shifting the whole table but deleting the entire row.
Sub deletedupe()
Dim i As Integer
Dim j As Integer
Dim k As Integer
Dim row1 As String
Dim row2 As String
i = 1
j = 1
k = 1
Do While Sheets("ws1").Cells(i, 1).Value <> ""
row1 = ""
j = 1
Do While Sheets("ws1").Cells(i, j).Value <> ""
row1 = row1 & Sheets("ws1").Cells(i, j).Value & " "
j = j + 1
Loop
k = i + 1
Do While Sheets("ws1").Cells(k, 1).Value <> ""
row2 = ""
j = 1
Do While Sheets("ws1").Cells(k, j).Value <> ""
row2 = row2 & Sheets("ws1").Cells(k, j).Value & " "
j = j + 1
Loop
If row1 = row2 Then
Sheets("ws1").Rows(k).EntireRow.Delete
Else
k = k + 1
End If
Loop
i = i + 1
Loop
End Sub
I have an excel sheet with the following data:
col1 col2 col3 col4
dvdtable 6 52 57
tvunit 2 30 31
I need to copy each row in another sheet, however making 6 copies of the dvdtable row and 2 copies of the tvunit row. (col2 is referring to the quantity). In addition I need to create a new column where for each of the 6 dvdtable rows I include 52,53,54,55,56,57 respectively in the new column. See the result below:
col1 col2 col3
dvdtable 6 52
dvdtable 6 53
dvdtable 6 54
dvdtable 6 55
dvdtable 6 56
dvdtable 6 57
tvunit 2 30
tvunit 2 31
I managed to produce the code that makes multiple copies of rows thanks to another question in your forum, but I am stuck with the last part of the programming, where I need to create the list of numbers within the range given in column 3 and column 4 for each type of furniture.
You likely have to change the sheetnames.
Option Explicit
Sub whyDidIDoThisForYou()
Dim i, j, k As Integer
Dim numbRows As Integer
Dim curWriteRow As Integer
Dim temp As Integer
Dim values() As String
numbRows = Range("a1").End(xlDown).Row - 1 'assumes heading
curWriteRow = 1
ReDim values(1 To numbRows, 1 To 4)
For i = 1 To numbRows
'read all values in from initial datasheet
For j = 1 To 4
values(numbRows, j) = Sheets("Sheet1").Cells(i + 1, j).Value
Next j
'write to next sheet
'get number of things to write
temp = values(numbRows, 4) - values(numbRows, 3)
'start writing the "output" sheet!
For j = 0 To temp
Sheets("Sheet2").Cells(curWriteRow, 1).Value = values(numbRows, 1)
Sheets("Sheet2").Cells(curWriteRow, 2).Value = values(numbRows, 2)
Sheets("Sheet2").Cells(curWriteRow, 3).Value = values(numbRows, 3) + j
curWriteRow = curWriteRow + 1
Next j
Next i
End Sub
You could use arrays as below which is much quicker than writing to ranges cell by cell
The code below
reads the orginal data into a variant array Y
loops through each row of Y (lngCnt2)
runs through that Y by the number of times specifiec in colulmB (lngCnt3)
dumps the new records to a second variant array X
dumps x to a range starting in E1 when finished
Sub SplicenDice()
Dim rng1 As Range
Dim lngCnt As Long
Dim lngCnt2 As Long
Dim lngCnt3 As Long
Dim lngCnt4 As Long
Dim X
Dim Y
Set rng1 = Range([a1], Cells(Rows.Count, "D").End(xlUp))
Y = rng1.Value2
lngCnt = Application.WorksheetFunction.Sum(Range("B:B"))
ReDim X(1 To lngCnt, 1 To 3)
For lngCnt2 = 1 To UBound(Y, 1)
For lngCnt3 = 1 To Y(lngCnt2, 2)
lngCnt4 = lngCnt4 + 1
X(lngCnt4, 1) = Y(lngCnt2, 1)
X(lngCnt4, 2) = Y(lngCnt2, 2)
X(lngCnt4, 3) = Y(lngCnt2, 3) + lngCnt3 - 1
Next
Next
[e1].Resize(UBound(X, 1), UBound(X, 2)).Value2 = X
End Sub