company is an array containing unknown number of companies;
For i = 1 To 50
Worksheets("Data_Claims").Activate
Range("A1").AutoFilter _
Field:=1, _
Criteria1:=company(i)
If IsEmpty(company(i)) = True Then
Exit For
Next i
If you want to filter the value within company, try this:
Worksheets("Data_Claims").Activate
Range("A1").AutoFilter _
Field:=1, _
Criteria1:=Array(company), _
Operator:=xlFilterValues
no need to use loop here
Related
Let's assume a chart with only values in the first two columns A and B like this
First I'd like to sort the chart alphabetically by column A, i.e. the Xs at top, then the Ys and the Zs.
The 2nd move should be a sorting of column B considering column A, i.e. keeping the block of Xs and sort their numbers in column B. The same with the blocks of Y and Z.
The 1st step works fine with the following code:
Sub sort()
Dim SortClmn As String
Dim Area As String
Area= "A1:B10"
SortClmn = "A"
ActiveSheet.Range(Area).Sort _
Key1:=Range(SortClmn & "1"), Order1:=xlDescending, _
Header:=xlGuess, MatchCase:=False, _
Orientation:=xlTopToBottom
End Sub
How do I need to change this code to apply the 2nd step?
Thanks in advance
The simplest method is to sort Column B and then sort Column A, this will achieve your desired effect.
Use the same method you used, but sort first column b then column a.
If I modify your code it would look as follows
Sub sort()
Dim SortClmn As String
Dim Area As String
Area = "A1:B10"
SortClmn = "B"
ActiveSheet.Range(Area).sort _
Key1:=Range(SortClmn & "1"), Order1:=xlAscending, _
Header:=xlGuess, MatchCase:=False, _
Orientation:=xlTopToBottom
Area = "A1:B10"
SortClmn = "A"
ActiveSheet.Range(Area).sort _
Key1:=Range(SortClmn & "1"), Order1:=xlAscending, _
Header:=xlGuess, MatchCase:=False, _
Orientation:=xlTopToBottom
End Sub
Record a macro;
Select the table;
In the ribbon - Data > Sort;
Select the first column that you want to sort;
Press Add Level;
Select the second column that you want to sort;
See the generated code;;
Refactor it, avoinding Select, Activate and putting the string variables;
Range.Sort Method MSDN
Sub sort()
lastRow = ActiveWorkbook.ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Row
With ActiveWorkbook.ActiveSheet.sort
.SortFields.Clear
.SortFields.Add Key:=Range("A1:A" & lastRow), Order:=xlAscending
.SortFields.Add Key:=Range("B1:B" & lastRow), Order:=xlAscending
.SetRange Range("A2:B" & lastRow)
.Header = xlNo
.Apply
End With
End Sub
Something like this?
I have seven different values that I wish to exclude using an AutoFilter.
I have tried the following code, but it gives an error:
.AutoFilter Field:=12, Criteria1:= _
"<>BESTPAYMENTS", Operator:=xlAnd, Criteria2:="<>IGL", Operator:=xlAnd, Criteria3:="<>MGBILLPAY", Operator:=xlAnd, Criteria4:="<>NDPL", Operator:=xlAnd, Criteria5:="<>RBPAYMENTS", Operator:=xlAnd, Criteria6:="<>TABCAB", Operator:=xlAnd, Criteria7:="<>TDNPAY"
Can someone help?
The AutoFilter method only supports two Criteria.
It is very easy to select multiple values for inclusion, e.g. by doing something like:
.AutoFilter Field:=12, _
Criteria1:=Array("first_value", _
"another_value", _
"something else", _
"and yet another one"), _
Operator:=xlFilterValues
However, it is a lot harder to exclude values, because of the implicit Or being used between elements in the array.
I believe you will need to use code similar to the following to achieve what you are after:
Dim r As Range
For Each r In .Columns(12).Cells
If r.Row <> .Row Then ' to avoid processing the header row
Select Case r.Value
Case "BESTPAYMENTS", _
"IGL", _
"MGBILLPAY", _
"NDPL", _
"RBPAYMENTS", _
"TABCAB", _
"TDNPAY"
r.EntireRow.Hidden = True
Case Else
r.EntireRow.Hidden = False
End Select
End If
Next
Unfortunately this just hides and unhides rows, rather than applying a true filter, but it is probably the best you can hope for.
I'm curious if there is a simpler solution out there with respect to retrieving values associated with a single ID in excel.
I have explored the INDEX solution to look up multiple values in a list but that is not really dynamic and gives you the result in a vertical order rather than the horizontal order that I required. (see Results desired below)
The sample function i used was this
"=IF(ISERROR(SMALL(IF(IF(ISERROR(SEARCH($A$9,$A$1:$A$7)),FALSE,TRUE),ROW($A$1:$A$7)),ROW($C$1:$C$7))),"",INDEX($A$1:$C$7,SMALL(IF(IF(ISERROR(SEARCH($A$9,$A$1:$A$7)),FALSE,TRUE),ROW($A$1:$A$7)),ROW($C$1:$C$7)),3))"
*Ignore the references for this example.
I have two sheets that I'm working on and basically need to retrieve the values associated with a single ID from "Numbers Sheet" and store them on "Master Sheet" See images below for clearer explanation. The formula needs to find the subsequent number associated with the ID and put it on the subsequent column as shown below.
*note: any user ID can request for any number of tickets so it can range from 1-100 (just showing 3 as an example)
Appreciate any guidance from the excel masters here. The only other solution I can think of is to use a vba code to retrieve each value and store it in an array and then retrieve the value from the array. Let me know your thoughts!
Thanks in advance!
Master Sheet:
Numbers Sheet:
Results desired:
Put the following formula in cell C2[1] of your Master Sheet
{=IFERROR(INDEX(Numbers!$A:$C,SMALL(IF(Numbers!$A$1:$A$1000=$A2,ROW(Numbers!$A$1:$A$1000)),INT((COLUMN(A:A)-1)/2)+1),MOD(COLUMN(A:A)-1,2)+2),"")}
[1] I'm assuming it is row 2 since you have unfortunately not shown the row numbers.
The formula is an array formula. Input it into the cell without the curly brackets and confirm it with [Ctrl] + [Shift] + [Enter]. The curly brackets then will appear automatically.
Then fill the formula to right and downwards as needed.
you can try this code
Sub main()
Dim IdRng As Range, cell As Range, filtCell As Range
Dim i As Long
With Worksheets("Master Sheet")
Set IdRng = .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).SpecialCells(XlCellType.xlCellTypeConstants)
End With
With Worksheets("Numbers")
With .Cells(1, 1).CurrentRegion
For Each cell In IdRng
.AutoFilter field:=1, Criteria1:=cell.value '<--| filter it on current department value
If Application.WorksheetFunction.Subtotal(103, .Cells.Resize(, 1)) > 1 Then
For Each filtCell In .Offset(1, 1).Resize(.Rows.Count - 1, 1).SpecialCells(XlCellType.xlCellTypeVisible)
cell.End(xlToRight).Offset(, 1).Resize(, 2).value = filtCell.Resize(, 2).value
Next filtCell
End If
Next cell
End With
.AutoFilterMode = False
End With
With Worksheets("Master Sheet").Cells(1, 1).CurrentRegion.Rows(1)
.Insert
With .Offset(-1)
.Font.Bold = True
.Resize(, 2) = Array("ID", "Name")
For i = 1 To .Columns.Count - 2 Step 2
.Offset(, 1 + i).Resize(, 2) = Array("Description " & (i + 1) / 2, "Number " & (i + 1) / 2)
Next i
End With
End With
End Sub
VBA is probably a better route for this and using .Find and .FindNext is the way I would go.
Attached is a generic FindAll function, so you could look for all the cells containing the ID in question then process the cells one at a time.
Function FindAll(What, _
Optional SearchWhat As Variant, _
Optional LookIn, _
Optional LookAt, _
Optional SearchOrder, _
Optional SearchDirection As XlSearchDirection = xlNext, _
Optional MatchCase As Boolean = False, _
Optional MatchByte, _
Optional SearchFormat) As Range
'LookIn can be xlValues or xlFormulas, _
LookAt can be xlWhole or xlPart, _
SearchOrder can be xlByRows or xlByColumns, _
SearchDirection can be xlNext, xlPrevious, _
MatchCase, MatchByte, and SearchFormat can be True or False. _
Before using SearchFormat = True, specify the appropriate settings for the Application.FindFormat _
object; e.g. Application.FindFormat.NumberFormat = "General;-General;""-"""
Dim SrcRange As Range
If IsMissing(SearchWhat) Then
Set SrcRange = ActiveSheet.UsedRange
ElseIf TypeOf SearchWhat Is Range Then
Set SrcRange = IIf(SearchWhat.Cells.Count = 1, SearchWhat.Parent.UsedRange, SearchWhat)
ElseIf TypeOf SearchWhat Is Worksheet Then
Set SrcRange = SearchWhat.UsedRange
Else: Set SrcRange = ActiveSheet.UsedRange
End If
If SrcRange Is Nothing Then Exit Function
'get the first matching cell in the range first
With SrcRange.Areas(SrcRange.Areas.Count)
Dim FirstCell As Range: Set FirstCell = .Cells(.Cells.Count)
End With
Dim CurrRange As Range: Set CurrRange = SrcRange.Find(What:=What, After:=FirstCell, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If Not CurrRange Is Nothing Then
Set FindAll = CurrRange
Do
Set CurrRange = SrcRange.Find(What:=What, After:=CurrRange, LookIn:=LookIn, LookAt:=LookAt, _
SearchDirection:=SearchDirection, MatchCase:=MatchCase, MatchByte:=MatchByte, SearchFormat:=SearchFormat)
If CurrRange Is Nothing Then Exit Do
If Application.Intersect(FindAll, CurrRange) Is Nothing Then
Set FindAll = Application.Union(FindAll, CurrRange)
Else: Exit Do
End If
Loop
End If
End Function
I´m writing a simple macro for searching my value in table. I know that searched value is in the document many times. But my macro finds just first value in table. I want select all rows with the value I´m looking for. Then I want copy selected rows and copy them to "sheet2". Can somebody help me adjust my macro? Thx
Sub Vyhladat()
Sheets("Sheet1").Columns(24).Find(What:=InputBox("Please enter your LR number", "Search")).Select
ActiveCells.EntireRow.Select
Selection.Copy
Sheets("Sheet2").Select
Range("A2").Select
Do
If IsEmpty(ActiveCell.Value) Then
ActiveCell.PasteSpecial xlPasteValues
End
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub
Here is how to do it (find the first match and then loop with the FindNext() method) :
Sub test_Jean()
Dim FirstAddress As String, _
cF As Range, _
RowsToCopy As String
ActiveSheet.Cells(1, 24).Activate
With ActiveSheet.Columns(24)
'First, define properly the Find method
Set cF = .Find(What:=InputBox("Please enter your LR number", "Search"), _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
'If there is a result, keep looking with FindNext method
If Not cF Is Nothing Then
FirstAddress = cF.Address
Do
cF.EntireRow.Copy
Sheets("Sheet2").Range("A" & Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row + 1).PasteSpecial xlPasteValues
Set cF = .FindNext(cF)
'Look until you find again the first result
Loop While Not cF Is Nothing And cF.Address <> FirstAddress
End If
End With
End Sub
Using this code I have set up I am using Filters which work in correlation with userforms with checkboxes to choose what to filter. Currently if I filter on one variable like Utilities it Filters, but if I move to another filter say Clients and then I filter instead of giving me the clients associated with the specific utility previously filtered it clears everything and filters only on the clients.
I am thinking the solution may have to deal with the Method:
.SpecialCells(xlCellTypeVisible)
Private Sub Cancel_UF_Click()
UtilityFilter.Hide
Range("A1").Select
End Sub
Private Sub Confirm_UF_Click()
ActiveSheet.Unprotect ("UMC626")
ClearFilter
UpdateFilters
UtilityFilter.Hide
Application.ScreenUpdating = False
Range("A1").Select
ActiveSheet.Protect Password:="UMC626", _
DrawingObjects:=False, _
Contents:=True, _
Scenarios:=True
End Sub
Sub SelectAll_UF_Click()
If SelectAll = True Then
Electricty_UF.Value = True
Gas_UF.Value = True
NonUtility_UF.Value = True
SolarElectricity_UF.Value = True
SolarThermal_UF.Value = True
SolidWaste_UF.Value = True
Water_UF.Value = True
Else
Electricity_UF.Value = False
Gas_UF.Value = False
NonUtility_UF.Value = False
SolarElectricity_UF.Value = False
SolarThermal_UF.Value = False
SolidWaste_UF.Value = False
Water_UF.Value = False
End If
End Sub
Sub UpdateFilters()
Integer_UF = -1
If Electricity_UF.Value = True Then
Add_UF String_UF, "E"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
If Gas_UF.Value = True Then
Add_UF String_UF, "G"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
If NonUtility_UF.Value = True Then
Add_UF String_UF, "NU"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
If SolarElectricity_UF.Value = True Then
Add_UF String_UF, "SE"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
If SolarElectricity_UF.Value = True Then
Add_UF String_UF, "SE"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
If SolarThermal_UF.Value = True Then
Add_UF String_UF, "ST"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
If SolidWaste_UF.Value = True Then
Add_UF String_UF, "SW"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
If Water_UF.Value = True Then
Add_UF String_UF, "W"
Range("E6:E67").AutoFilter Field:=1, _
Criteria1:=String_UF, _
Operator:=xlFilterValues
End If
End Sub
Sub Add_UF(String_UF() As String, NewValue As String)
Integer_UF = Integer_UF + 1
ReDim Preserve String_UF(Integer_UF)
String_UF(Integer_UF) = NewValue
End Sub
I think the focus should be on Add_UF
I am calling a NewValue. Is there anyway to sort a column after it has been sorted? As you can see in the picture below I'd like to beable to sort one colum. Say on Energy then after that sort it on Work Type.
I do not intend to re-write your code but I can provide the information, and methods, that you will need to achieve what you want.
Currently you are focusing on a single column:
Range("E6:E67").AutoFilter Field:=1, _
You should extend this to the whole table area:
ActiveSheet.Range("$A$5:$M$112").AutoFilter Field:=6, Criteria1:="Leeds"
The number 6 is the sixth column within the filter range. You might also create a Range reference to refer to the filter-range:
Dim rngFilter As Range
Set rngFilter = Worksheets("Staff List").AutoFilter.Range
The filters accumulate, so the following will filter on two columns:
ActiveSheet.Range("$A$5:$M$112").AutoFilter Field:=6, Criteria1:="Leeds"
ActiveSheet.Range("$A$5:$M$112").AutoFilter Field:=7, Criteria1:="Sales"
At some point you will Clear the filters:
ActiveSheet.ShowAllData
Clearing a single filter is just applying a filter with no criteria:
ActiveSheet.Range("$A$5:$M$112").AutoFilter Field:=7
If you record a macro to Sort on more than one column (using Custom Sort) it creates code like the following, to which I've added some comments:
'clear the previous Sort
ActiveWorkbook.Worksheets("Staff List").AutoFilter.Sort.SortFields.Clear
'accumulate the SortFields
ActiveWorkbook.Worksheets("Staff List").AutoFilter.Sort.SortFields.Add Key:= _
Range("C6:C112"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
ActiveWorkbook.Worksheets("Staff List").AutoFilter.Sort.SortFields.Add Key:= _
Range("B6:B112"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption _
:=xlSortNormal
'Apply the Sort
With ActiveWorkbook.Worksheets("Staff List").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.Apply
End With
Recording Macros will also reveal other methods and properties that may be useful to you. The recorded code will not be elegant, and can be reduced (tidied) significantly, but it does provide useful information.