VBA Select columns of visible rows from filtered table into another sheet - excel

I wanted to add the following: After having sorted the Table I apply a Filter on it. I only require the information of 2 columns of the visible rows. and want to copy that inforation to another sheet.
This is what I have got so far but I am not able to selected the visible Rows from the filtered table.
And here is an image of the filtered Data. I need the data of Column "A" and "H" without the Header
I tried selecting the range of the ActiveSheets Listobject with the SpecialCellValue parameter but i couldnt figure out how to grab it.
Sub TabelleEinzeln()
Dim rep As Long
Dim table_name As String
Dim outcome_KW As String
For rep = Range("O4").Value To Range("P4").Value
Dim SortOrder As Integer
Dim sheet_name As String
sheet_name = Sheets("Admin").Range("H" & rep).Value
table_name = Sheets("Admin").Range("I" & rep).Value
outcome_KW = Sheets("Admin").Range("L" & rep).Value
Sheets(sheet_name).Select
Dim lo As ListObject
Set lo = ActiveSheet.ListObjects.Add(xlSrcRange, Range("$A$8:$K$2276"), , xlYes)
' Example how to sort
With lo.Sort
.SortFields.Clear
.SortFields.Add Key:=lo.DataBodyRange.Columns(1), SortOn:=xlSortOnValues, Order:=xlAscending
.Header = xlYes
.Apply
End With
'Top 5 höchsten Werte und sortiert
lo.Range.AutoFilter Field:=8, Criteria1:= _
"5", Operator:=xlTop10Items
'Here i want to selected the filtered outcome and past it to the new sheet
'.Copy Sheets("KW_Bericht_Report").Range("outcome_KW")
Next rep
Sheets("Admin").Select
MsgBox ("Tables have been created for every imported sheet")
End Sub

Related

conditional filtering excel macros

I recorded this macro where I make 3 filters, (by status, by substatus, and by country) once completed I want to save the results in a new spreadsheet with a custom name, the issue is when any of the option filter does not exist.
for example, if "costa rica" does not exist in the selection I get and weird result, in the event costa rica does not exist I would like to still create the new file but only copy and paste fist row of the original file into the new file.
Please help.
Sub filtrado()
ActiveSheet.ListObjects("SEGUIMIENTO").Range.AutoFilter Field:=2, Criteria1 _
:="Closed"
ActiveSheet.ListObjects("SEGUIMIENTO").Range.AutoFilter Field:=3, Criteria1 _
:=Array("In Progress", "Pending", "Pending Customer", "Updated by Customer"), _
Operator:=xlFilterValues
ActiveSheet.ListObjects("SEGUIMIENTO").Range.AutoFilter Field:=5, Criteria1 _
:="Costa Rica"
Cells.Select
Selection.Copy
Sheets("Sheet1").Select
ActiveSheet.Paste
End Sub
You need to check if there are any visible rows so that you can copy the data.
Sub filtrado2()
Dim ws As Worksheet: Set ws = ActiveSheet
Dim ol As ListObject: Set ol = ws.ListObjects("SEGUIMIENTO")
Dim olCol As Integer
Dim srcRng As Range, dstRng As Range
' filter column 2
olCol = ol.ListColumns("Column2").Index
ol.Range.AutoFilter Field:=olCol, Criteria1:="Closed"
' filter column 3
olCol = ol.ListColumns("Column3").Index
ol.Range.AutoFilter Field:=olCol, Criteria1 _
:=Array("In Progress", "Pending", "Pending Customer", "Updated by Customer"), _
Operator:=xlFilterValues
' filter column 5
olCol = ol.ListColumns("Column5").Index
ol.Range.AutoFilter Field:=5, Criteria1:="Costa Rica1"
' check visible rows
On Error Resume Next
Dim olRowsVisible As Integer
olRowsVisible = ol.ListColumns(1).DataBodyRange.SpecialCells(xlCellTypeVisible).Count
On Error GoTo 0
' copy only if any rows visible
If olRowsVisible > 0 Then
Set srcRng = Range.SpecialCells(xlCellTypeVisible) ' copies the table header and visible rows
Set dstRng = ws.Range("N1")
srcRng.Copy dstRng
Application.CutCopyMode = False
End If
End Sub

When a match is found, copy row from one sheet to the row where the match was found in macro

I have a table on the MainDashboard that is updated by a macro. It copies data from selected sheets and updates this main table. Here is my code but I am stuck. I need it to:
Loop through every sheet in Sheet List
Loop through every value in the first column of the tables on each sheet
Check to see if these IDs are in the first column of the Main Dashboard table
If yes, Copy everything on that row and paste it over the same row where the value was found on the main Dashboard table
If no, add it to the bottom of the row
When finished have a MsgBox that says, you have modified x entries and added x new entries
Sub Update()
Dim SheetList As Variant
Dim x As Long
Dim TaskListTable As Range
Dim TaskList As ListObject
Dim SortColumn As Range
Dim TaskId As Integer
Dim LastRow As Range
Dim MDLastRow As Range
'What I want the Excel program to do before I start
With Application
.ScreenUpdating = False
.StatusBar = "Running..."
End With
'List Sheet Names into an Array Variable
SheetList = Array(S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14)
'Loop through list
For x = LBound(SheetList) To UBound(SheetList)
'Code will fail unless you activate the sheet first
SheetList(x).Activate
'Loop for b15 in column 1 down for every row to last row
LastRow = Range("B" & Rows.Count).End(xlUp).Row
MDLastRow = Range("B" & Rows.Count).End(xlUp).Row
For Each TaskID In Range("B15": LastRow)
If WorksheetFunction.Match(Range("B15:MDLastRow"), Then
SheetList(x).Range("TaskID").End(xlRight).Copy
'PASTE TO ENTIRE ROW WHERE THE MATCH WAS FOUND
End If
'Else add row to the bottom
SheetList(x).Range("TaskID").End(xlRight).Copy
MainDashboard.Range("B" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteAll
Next x
MainDashboard.Activate
'MsgBox
'You have Modified X tasks
'You have Added X tasks
'Sort the table by the latest Date
Set TaskList = MainDashboard.ListObjects("Task_List")
Set SortColumn = Range("Task_List[DATE]")
With TaskList.Sort
.SortFields.Clear
.SortFields.Add Key:=SortColumn, SortOn:=xlSortOnValues, Order:=xlAscending
.Header = xlYes
.Apply
End With
'What I want the Excel program to do after I have finished
With Application
.ScreenUpdating = True
.StatusBar = "Complete"
.CutCopyMode = False
End With
End Sub
Thanks in advance

Sorting a Range based on sheet variable with VBA

Scenario: I have a sheet and am trying to sort a part of it. Inside the sheet I have a dropdown list, which allows me to select the values (aaa, bbb, ccc). Each of those values represent a column and when selected, the code should sort the range by that column.
Problem: The process works for one of the values in the dropdown list, but not for the others (it runs, but nothing happens).
Code:
Sub ratecolumnssort()
Dim LastRow As Integer
Dim sortColumn As String, sortAgent As String
shtMonitoring.Activate
LastRow = shtMonitoring.Cells(shtMonitoring.rows.count, "B").End(xlUp).row
sortAgent = shtMonitoring.Cells(8, 9) ' this is where the dropdown with values aaa, bbb and ccc is
If sortAgent = "aaa" Then
sortColumn = "F"
ElseIf sortAgent = "bbb" Then
sortColumn = "H"
ElseIf sortAgent = "ccc" Then
sortColumn = "J"
End If
With ActiveSheet.sort
.SortFields.Add key:=Range(sortColumn & "11"), Order:=xlAscending
.SetRange Range("B11", "N" & LastRow )
.Header = xlYes
.Apply
End With
End Sub
Question: What am I doing wrong here?
You need to clear the sort settings first.
With ActiveSheet.Sort
.SortFields.Clear 'add this line
'as before

Creating chart on one sheet based on dynamic auto filter in another sheet - returning incorrect range

I have an excel workbook with multiple sheets. The first sheet is a dashboard on which I display charts based on data from other sheets.
I have a sheet called Daily Score. In it are three columns:
User ID, Sum_PointsAdded, Day_Timestamp
On any given day, a user can have a row inserted with the points they added and the date added.
The header row starts on A3 and has auto filter applied.
On the dashboard I have created a button that asks the user to insert a UserID via an input box. Based on that data, I filter the data to show only that user's score.
A sample result would be:
User ID Sum_PointsAdded Day_Timestamp
777 38 28/3/19
777 11 20/3/19
777 44 2/4/19
777 24 13/5/19
The chart I add is a line chart and should show only one line (and one entry type in the legend).
The X axis is the date and the Y axis is the score.
If I manually use the filter on the Daily Score sheet, and then I click the button on the Dashboard sheet and request the filter, the chart appears OK. However, if I simply click the chart button on the dashboard and don't fiddle with the filter, the chart I get has a line for Sum_PointsAdded and a line for Day_Timestamp (that I shouldn't get) and no line for score.
The legend has four entries: Score, Sum_PointsAdded, Day_Timestamp and Series4
I'm assuming I'm doing something wrong with the filter or the definitions of the range for the chart. However I do have another chart on the dashboard sheet with the exact same set up (just with two lines on the chart), and there I have no problem.
I've tried changing the location of the range definitions but it doesn't seems to work.
Note: these are dynamic ranges.
Here's my code:
Public Sub CreateDailyScoreChart()
Dim WS As Worksheet
Dim WS2 As Worksheet
Dim Rng1 As Range
Dim Rng2 As Range
Dim myValue As Variant
Dim LastRow As Long
Dim FirstRow As Long
Application.ScreenUpdating = False
Set WS = ThisWorkbook.Sheets("Daily Score")
Set WS2 = ThisWorkbook.Sheets("Dashboard")
With WS
'set last row for entire table in order to define range
LastRow = .Range("A" & Rows.Count).End(xlUp).Row
Set Rng1 = .Range("A3:A" & LastRow)
Set Rng2 = .Range("C3:C" & LastRow)
End With
'Input UserID
myValue = InputBox("Insert UserID")
'Filter based on UserID, for this month decending
Sheets("Daily Score").Activate
On Error Resume Next
ActiveSheet.ShowAllData
Rng1.CurrentRegion.AutoFilter Field:=1, Criteria1:="=" & myValue
On Error GoTo 0
With WS.AutoFilter.Sort
.SortFields.Clear
.SortFields.Add2 Key _
:=Rng2, SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Rng2.AutoFilter Field:=3, Criteria1:=13, _
Operator:=11, Criteria2:=0, SubField:=0
With WS
FirstRow = .AutoFilter.Range.Offset(1).SpecialCells(xlCellTypeVisible).Row
'reset last row for filtered table
LastRow = .Range("A" & Rows.Count).End(xlUp).Row
End With
'Delete existing chart if it exists
On Error Resume Next
With WS2
.ChartObjects("DailyScore").Activate
.ChartObjects("DailyScore").Delete
End With
On Error GoTo 0
'Add new chart
'ThisWorkbook.Sheets("Dashboard").Shapes.AddChart2(322, xlLineMarkers).Select
WS.Activate
WS.Shapes.AddChart2(332, xlLineMarkers).Select
Dim Chart As Chart
Set Chart = ActiveChart
'Defining X and Y Axis values
Dim xRng As Range
Dim vRng1 As Range
With WS
Set xRng = .Range(.Cells(FirstRow, 3), .Cells(LastRow, 3))
Set vRng1 = .Range(.Cells(FirstRow, 2), .Cells(LastRow, 2))
End With
'Adding series 1
Chart.SeriesCollection.NewSeries
Chart.FullSeriesCollection(1).XValues = xRng
Chart.FullSeriesCollection(1).Values = vRng1
Chart.FullSeriesCollection(1).Name = "Score"
Chart.SetElement (msoElementLegendBottom)
Chart.SetElement (msoElementChartTitleAboveChart)
Selection.Caption = "User " & myValue & " Daily Score This Year"
Chart.Parent.Name = "DailyScore"
Chart.ChartArea.Select
Chart.Parent.Cut
Sheets("Dashboard").Select
Sheets("Dashboard").Activate
Range("K20").Select
ActiveSheet.Paste
Application.ScreenUpdating = True
End Sub
Writing this in answer mode to help others:
Following the Set Chart = ActiveChart
add ActiveChart.ChartArea.ClearContents
Chart content should be emptied and chart will come back with desired result after the code completes its run.

How to delete rows in an Excel ListObject based on criteria using VBA?

I have a table in Excel called tblFruits with 10 columns and I want to delete any rows where the Fruit column contains Apple. How can I do this?
The following sub works:
Private Sub deleteTableRowsBasedOnCriteria(tbl As ListObject, columnName As String, criteria As String)
Dim x As Long, lastrow As Long, lr As ListRow
lastrow = tbl.ListRows.Count
For x = lastrow To 1 Step -1
Set lr = tbl.ListRows(x)
If Intersect(lr.Range, tbl.ListColumns(columnName).Range).Value = criteria Then
'lr.Range.Select
lr.Delete
End If
Next x
End Sub
The sub can be executed like this:
Dim tbl As ListObject
Set tbl = ThisWorkbook.Worksheets("Sheet1").ListObjects("tblFruits")
Call deleteTableRowsBasedOnCriteria(tbl, "Fruit", "Apple")
Well, it seems the .listrows property is limited to either ONE list row or ALL list rows.
Easiest way I found to get around this was by:
Setting up a column with a formula that would point out to me all rows I would like to eliminate (you may not need the formula, in this case)
Sorting the listobject on that specific column (preferably making it so that my value to be deleted would be at the end of the sorting)
Retrieving the address of the range of listrows I will delete
Finally, deleting the range retrieved, moving cells up.
In this specific piece of code:
Sub Delete_LO_Rows
Const ctRemove as string = "Remove" 'value to be removed
Dim myLO as listobject, r as long
Dim N as integer 'number of the listcolumn with the formula
Set myLo = Sheet1.ListObjects("Table1") 'listobject goes here
With myLO
With .Sort
With .SortFields
.Clear
.Add Key:=.HeaderRowRange(myLO.ListColumns(N)), SortOn:= _
xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
End With
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
On Error GoTo NoRemoveFound
r = Application.WorksheetFunction.Match(ctRemove, .ListColumns(.ListColumns.Count).DataBodyRange, 0)
Range(.parent.name & "!" & .DataBodyRange(r, 1).Address & ":" & .DataBodyRange(.ListRows.Count, .ListColumns.Count).Address).Delete xlShiftUp
'Added the .parent.name to make sure the address is on the correct sure, but it will fail if there are any spaces or characters on the sheet name that will make it need a pair of '.
'The error is just to skip these two lines in case the match returns an error. There's likely a better/cleaner way to do that.
NoRemoveFound:
End With
End sub
Hope it helps...

Resources