I am writing a program that should sum only the row with a lower case c. The code I have now, sums all rows beginning with c, regardless if upper or lower case. How I can I write it so that it is case sensitive?
Here is what I have so far:
Sub summ()
Dim iArea As Long
With Worksheets("K00304.RPT")
With .Range("A14", .Cells(.Rows.Count, 1).End(xlUp))
.Cells(2, 1).Value = "ZERO"
.AutoFilter field:=1, Criteria1:="ZERO*"
With .Resize(.Rows.Count -
1).Offset(1).SpecialCells(xlCellTypeVisible) '.Offset(-1)
For iArea = 1 To .Areas.Count - 1
With .Parent.Range(.Areas(iArea).Offset(1), .Areas(iArea +
1).Offset(-1))
Worksheets("Total").Cells(Rows.Count,
"AF").End(xlUp).Offset(1).Value = WorksheetFunction.SumIf(.Cells, "c*",
.Offset(, 7))
End With
Next
End With
.Cells(2, 1).ClearContents
End With
.AutoFilterMode = False
End With
Many Thanks!
You can compare the characters with StrConv():
Sub t()
Dim cel As Range
Set cel = Range("A1")
If StrConv(Left(cel, 1), vbProperCase) = Left(cel, 1) And Left(cel, 1) = "C" Then
'There's a match, the left letter is capitalized.
Debug.Print "'C' is present"
End If
End Sub
Edit: Actually, just checking If LEFT(cel,1) = "C" Then seems to work too.
I would use the Evaluate function and sumproduct formula, hopefully this works.
Sub summ()
Dim iArea As Long
With Worksheets("K00304.RPT")
With .Range("A14", .Cells(.Rows.Count, 1).End(xlUp))
.Cells(2, 1).Value = "ZERO"
.AutoFilter field:=1, Criteria1:="ZERO*"
With .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible) '.Offset(-1)
For iArea = 1 To .Areas.Count - 1
With .Parent.Range(.Areas(iArea).Offset(1), .Areas(iArea + 1).Offset(-1))
Dim criteria_range As String
Dim sum_range As String
Dim criteria As String
Dim sum_ifs_case_sensitive As Long
criteria = "c"
criteria_range = .Cells.Address
sum_range = .Offset(, 7).Address
sum_ifs_case_sensitive = Evaluate("SUMPRODUCT(--(ISNUMBER(FIND(" & Chr(34) & criteria & Chr(34) & "," & criteria_range & ")))," & sum_range & ")")
Worksheets("Total").Cells(Rows.Count, "AF").End(xlUp).Offset(1).Value = sum_ifs_case_sensitive
End With
Next
End With
.Cells(2, 1).ClearContents
End With
.AutoFilterMode = False
End With
End Sub
Related
I want to filter all the values except value in Array i.e. "B400", "A200", "C300".
I tried following code, none of the code is working
Dim rDataRange as Range
set rDataRange = Range("A1:P1000")
rDataRange.AutoFilter Field:=11, Criteria1:="<>" & Array("B400", "A200", "C300"), Operator:=xlFilterValues
rDataRange.AutoFilter Field:=11, Criteria1:=Array("<>B400", "<>A200", "<>C300"), Operator:=xlFilterValues
Please help me
Modified for your situation:
Option Explicit
Sub AutoFilterWorkaround()
Dim sht As Worksheet
Dim filterarr As Variant, tofindarr As Variant
Dim lastrow As Long, i As Long, j As Long, k As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
'List the parts of the words you need to find here
tofindarr = Array("B400", "A200", "C300")
ReDim filterarr(0 To 0)
j = 0
For i = 2 To lastrow
If sht.Cells(i, 11).Value <> tofindarr(0) And _
sht.Cells(i, 11).Value <> tofindarr(1) And _
sht.Cells(i, 11).Value <> tofindarr(2) Then
filterarr(j) = sht.Cells(i, 11).Value
j = j + 1
ReDim Preserve filterarr(0 To j)
End If
Next i
'Filter on array
sht.Range("$A$1:$P$" & lastrow).AutoFilter Field:=11, Criteria1:=Array(filterarr), Operator:=xlFilterValues
End Sub
There is an easier way to accomplish this then using a filter.
Dim lRow As Long
With ThisWorkbook.Sheets(1)
lRow = .Range("K" & Rows.Count).End(xlUp).Row
For i = 2 To lRow
If .Cells(i, 11).Value = "A200" Or .Cells(i, 11).Value = "B400" Or .Cells(i, 11).Value = "C300" Then
.Cells(i, 11).EntireRow.Hidden = True
End If
Next i
End With
you could still use AutoFilter() in a sort of reverse mode:
Dim myRng As Range ' helper range variable
With Range("A1:P1000") ' reference wanted range to filter, header row included
.AutoFilter field:=11, Criteria1:=Array("B400", "A200", "C300"), Operator:=xlFilterValues ' filter on "not wanted" values
If Application.Subtotal(103, .Resize(, 1)) > 1 Then ' if any filtered cell other than header row
Set myRng = .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) ' temporarily set 'myRng' to referenced range "not wanted" rows
.Parent.AutoFilterMode = False ' remove filters and show all rows
myRng.EntireRow.Hidden = True ' hide referenced range "not wanted" rows, leaving "wanted" rows only visible
With .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) ' reference referenced range "wanted" rows
.Select
' do what you want with "wanted" rows
End With
.EntireRow.Hidden = False ' unhide all referenced range rows
Else
.Parent.AutoFilterMode = False ' remove filters
End If
End With
Sub test_calculateval()
Dim rnData, r As Range, ThisYearID, LR, FR, EndR, HomeCount, AwayCount, DrawCount, i As Long, Hometeam As String
ThisYearID = Sheet5.Cells(2, 1).Value - 1
Hometeam = Sheet5.Cells(2, 5)
HomeCount = 0
With Sheet1
Set rnData = Range(Range("A2"), Range("R2").End(xlDown))
With rnData
Rows("1:1").Select
Selection.AutoFilter
ActiveSheet.Range(Range("A2"), Range("R2").End(xlDown)).AutoFilter Field:=1, Criteria1:=">" & ThisYearID - 5
ActiveSheet.Range(Range("A2"), Range("R2").End(xlDown)).AutoFilter Field:=5, Criteria1:=Hometeam
LR = Range("A" & Rows.count).End(xlUp).Row
Set r = ActiveSheet.Range("A2:R" & LR).Rows.SpecialCells(xlCellTypeVisible)
FR = r.Row
EndR = Range("A" & FR).End(xlDown).Row
For Each rngarea In .SpecialCells(xlCellTypeVisible).Areas
If Range("K2:K" & LR).SpecialCells(xlCellTypeVisible).Value = "H" Then
HomeCount = HomeCount + 1
End If
Next
End With
End With
MsgBox HomeCount
End Sub
I want to check if each cell in column K (after filtering) is equal to "H", and count them.
This code is throwing a type mismatch error, what seems to be the problem
Since it is possible that
Range("K2:K" & LR).SpecialCells(xlCellTypeVisible).Value
might be returning multiple cells, so it cannot be compared to a single string value. In simple words, we cannot calculate the value of multiple cells, when they are returned to a range. The solution applies a third filter to the filtered range which filters all the records having value "H" in the column K and then we count all the visible cells.
This code will turn out to be faster than doing the same thing via loops.
Replace this existing code with this one:
Sub test_calculateval()
Dim rnData, r As Range, ThisYearID, LR, FR, EndR, HomeCount, AwayCount, DrawCount, i As Long, Hometeam As String
ThisYearID = Sheet5.Cells(2, 1).Value - 1
Hometeam = Sheet5.Cells(2, 5)
HomeCount = 0
With Sheet1
Set rnData = Range(Range("A2"), Range("R2").End(xlDown))
With rnData
.AutoFilter
.AutoFilter Field:=1, Criteria1:=">" & ThisYearID - 5
.AutoFilter Field:=5, Criteria1:=Hometeam
.AutoFilter Field:=11, Criteria1:="=H", Operator:=xlAnd
HomeCount = .Columns("K2:K" & (rnData.Rows.Count)).SpecialCells(xlCellTypeVisible).Count-1
End With
End With
MsgBox HomeCount
End Sub
I jus want to select consequent cells in a single row, until a certain cell, with the value "Total" in it. How do I do this in VBA? I'm making a VBA procedure which relies on the length of the row, which must be dynamic (the length can change).
Sub test()
Dim myRow As Long
Dim rngEnd As Range
Dim rngToFormat As Range
myRow = 4
Set rngEnd = Rows(myRow).Find("total")
If Not rngEnd Is Nothing Then
Set rngToFormat = Range(Cells(myRow, 1), rngEnd)
Debug.Print rngToFormat.Address
Else
Debug.Print "No total on row " & myRow
End If
End Sub
Inside a sub:
For i = 1 To 9999
If ActiveCell.Offset(0, i).Value = "Total" Then Exit For
If ActiveCell.Offset(0, 1).Value = "" Then Exit For
Next
If ActiveCell.Offset(0, i).Value = "Total" Then Range(Cells(ActiveCell.Row, ActiveCell.Column), Cells(ActiveCell.Row, ActiveCell.Column + i - 1)).Select
The macro select from Activecell to the value of "Total".
If you want from the column 5 (sample):
For i = 1 To 9999
If ActiveCell.Offset(0, i).Value = "Total" Then Exit For
If ActiveCell.Offset(0, 1).Value = "" Then Exit For
Next
If ActiveCell.Offset(0, i).Value = "Total" Then Range(Cells(ActiveCell.Row, 5), Cells(ActiveCell.Row, ActiveCell.Column + i - 1)).Select
Sub FindTotal()
Dim rng As Variant
rng = Rows(20) ' Then number of the row where "Total" is. Keep in mind that this will add all columns to rng and which will use a lot of memory. If you can limit the number of columns to be added e.g. rng = Range("A20:Z20") as long as Total will always be within the range
i = 1
While rng(1, i) <> "Total"
i = i + 1
Wend
End Sub
I'm using this script to insert fill with rows where non-sequential is produced in a column of an excel file.
Sub InsertValueBetween()
Dim lastrow As Long
Dim gap As Long
Dim i As Long, ii As Long
Application.ScreenUpdating = False
With ActiveSheet
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
For i = lastrow To 3 Step -1
gap = .Cells(i, "A").Value - .Cells(i - 1, "A").Value
If gap > 1 Then
.Rows(i).Resize(gap - 1).Insert
End If
Next i
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
.Cells(3, "A").Value = .Cells(2, "A").Value + 1
.Cells(2, "A").Resize(2).AutoFill .Cells(2, "A").Resize(lastrow - 1)
End With
End Sub
In addition to adding these new rows I want them to also have a specific value in column B. I'm trying to implement this but with no result.
Anybody could help me?
One way you could tackle this challenge is with a Range variable. Here is some heavily-commented code that walks through the process:
Sub InsertValueBetweenRev2()
Dim Target As Range '<~ declare the range variable
'... declare your other variables
'... do other stuff
For i = lastrow To 3 Step -1
gap = .Cells(i, "A").Value - .Cells(i - 1, "A").Value
If gap > 1 Then
.Rows(i).Resize(gap - 1).Insert
'the next line sets the range variable to the recently
'added cells in column B
Set Target = .Range(.Cells(i, 2), .Cells(i + gap - 2, 2))
Target.Value = "Cool" '<~ this line writes text "Cool" into those cells
End If
Next i
'... the rest of your code
End Sub
So, to sum it up, we know that gap - 1 rows are going to be added, and we know that the new rows are added starting at row i. Using that knowledge, we assign the just-added cells in column B to a Range then set the .value of that Range to whatever is needed.
a Better way of doing it with less variables and faster:
Sub InsRowWithText()
Dim LR As Long, i As Long
LR = Range("D" & Rows.Count).End(xlUp).row
For i = LR To 3 Step -1
If Range("D" & i).Value <> Range("D" & i - 1).Value Then
Rows(i).Resize(1).Insert
Range("D" & i).Value = "Test"
End If
Next i
End Sub
This is how i utilized it:
Sub InsRowWithText()
Dim strMsg As String, strTitle As String
Dim LR As Long, i As Long
Text = "ADD"
strMsg = "Warning: This is a Advanced Function, Continue? "
strTitle = "Warning: Activated Advanced Function "
If MsgBox(strMsg, vbQuestion + vbYesNo, strTitle) = vbNo Then
Exit Sub
Else
Sheets("SAP Output DATA").Select
If Range("D3").Value = Text Then
MsgBox "Detected That This Step Was Already Completed, Exiting."
Exit Sub
End If
application.ScreenUpdating = False
LR = Range("D" & Rows.Count).End(xlUp).row
For i = LR To 3 Step -1
If Range("D" & i).Value <> Range("D" & i - 1).Value Then
Rows(i).Resize(1).Insert
Range("D" & i).EntireRow.Interior.ColorIndex = xlColorIndexNone
Range(("A" & i), ("D" & i)).Value = Text
End If
Next i
End If
Range("D2").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1).Select
Range(("A" & ActiveCell.row), ("D" & ActiveCell.row)).Value = Text 'last row doesnt get text for some reason.
ActiveCell.EntireRow.Interior.ColorIndex = xlColorIndexNone
ActiveCell.Offset(1).Select
Range(("D" & ActiveCell.row), ("E" & ActiveCell.row)).Interior.ColorIndex = 17 'purple
application.ScreenUpdating = True
Range("D3").Select
End Sub
I need to filter a data table where 3 columns can contain the result I am looking for:
So if the criteria is found in columns 1, 2 or 3 then the row should be returned.
(source: gulfup.com)
So in the above sample data lets say I select the criteria as "Fat"
I am looking for the autofilter to return rows 1 & 2; if I select the criteria as "Funny" I need rows 2 & 6 and so on....
Below is my code which is not working since apparently it tries to find the rows in which all columns contain the criteria, and it is not what I am looking to do.
With Sheet1
.AutoFilterMode = False
With .Range("A1:D6")
.AutoFilter
.AutoFilter Field:=2, Criteria1:="Fat", Operator:=xlFilterValues
.AutoFilter Field:=3, Criteria1:="Fat", Operator:=xlFilterValues
.AutoFilter Field:=4, Criteria1:="Fat", Operator:=xlFilterValues
End With
End With
I have also tried to use Operator:=xlor but when I ran the code it returned no results.
In short: The row must be returned by the filter is the criteria is found in column B or C or D.
Help is definitely appreciated.
As follow up from comments, there are two ways for you.
Use additional column with formula:
Dim copyFrom As Range
With Sheet1
.AutoFilterMode = False
With .Range("A1:E6")
'apply formula in column E
.Columns(.Columns.Count).Formula = "=OR(B1=""Fat"",C1=""Fat"",D1=""Fat"")"
.AutoFilter Field:=5, Criteria1:=True
On Error Resume Next
Set copyFrom = .Offset(1).Resize(.Rows.count - 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
End With
End With
If Not copyFrom Is Nothing Then copyFrom.EntireRow.Copy
Use For loop with Union:
Dim copyFrom As Range
Dim i As Long
With Sheet1
For i = 2 To 6
If .Range("B" & i) = "Fat" Or .Range("C" & i) = "Fat" Or .Range("D" & i) = "Fat" Then
If copyFrom Is Nothing Then
Set copyFrom = .Range("B" & i)
Else
Set copyFrom = Union(.Range("B" & i), copyFrom)
End If
End If
Next
End With
If Not copyFrom Is Nothing Then copyFrom.EntireRow.Copy
For copying also header:
Dim copyFrom As Range
Dim i As Long
With Sheet1
Set copyFrom = .Range("B1")
For i = 2 To 6
If .Range("B" & i) = "Fat" Or .Range("C" & i) = "Fat" Or .Range("D" & i) = "Fat" Then
Set copyFrom = Union(.Range("B" & i), copyFrom)
End If
Next
End With
copyFrom.EntireRow.Copy
UPDATE:
Dim hideRng As Range, copyRng As Range
Dim i As Long
Dim lastrow As Long
With Sheet1
lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
.Cells.EntireRow.Hidden = False
For i = 2 To lastrow
If Not (.Range("B" & i) = "Fat" Or .Range("C" & i) = "Fat" Or .Range("D" & i) = "Fat") Then
If hideRng Is Nothing Then
Set hideRng = .Range("B" & i)
Else
Set hideRng = Union(.Range("B" & i), hideRng)
End If
End If
Next
If Not hideRng Is Nothing Then hideRng.EntireRow.Hidden = True
On Error Resume Next
Set copyRng = .Range("B1:B" & lastrow).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
End With
If copyRng Is Nothing Then
MsgBox "There is no rows matching criteria - nothing to copy"
Exit Sub
Else
copyRng.EntireRow.Copy
End If