VBA reading cell values into a list then using it - vba

I have a long list of data, one line for one movement. I need to check the volumes of the movements by location. The locations can be grouped, as some of them has the same criteria for filtering. For doing that I would like to read the cell values into a list and then looping through the original list of data by checking into which group does the location belongs. I don't know how to read the group into a list in a way that then I can check if a cell value matches with any of the items in the original - to be filtered - list.
Can anyone help with it? Also, in case you have any other suggestion for the solution, I appreciate it too.
Thanks!!

Please provide us your own solution or at least a attempts to present your effort. Without any data or code to analyze I can suggest sth like this:
Sub Make_a_List()
Dim TableWithData() as Variant
TableWithData = Range(Cells(1,1),Cells(100,100)) 'Values as example
End Sub
This gives you an table with elements of the specified range. For one row you will get one dimension table.
Then for instance you can make a for loop:
For i=1 to Ubound(TableWithData)
if TableWithData(i) = sth then
do whatever you need
end if
Next i

Related

Multiple Criteria using autofilter on the same range, autofilter only takes last Criteria Used

I'm trying to filter multiple filters based on user input from a listbox on the same range.
However, for some reason the autosort method only sort the target range using the last criteria from testing.
I have searched everywhere, tested out array solutions (reading list info into an array), writing a range of values for filters on worksheets, changing variable type/operator to no avail. Nothing works.
Thanks for your time for reading this, would appreciate it if someone could help me with this.
dim lifecycle as range
dim List2String as string
Set lifeCycle = defineColRange(startWs, "Lifecycle Comments (Saks)", True, False)
For i = 0 To ListBox2_Lifecomments.ListCount - 1
'looping though the listbox2 to retrieve values
List2String = ListBox2_Lifecomments.List(i)
startWs.UsedRange.AutoFilter Field:=lifeCycle.Column, Criteria1:="<>" & List2String
Next i
startWs.UsedRange.SpecialCells(xlCellTypeVisible).Interior.Color = rgbLightPink 'testing to see if filter works
After some more digging, and rethinking, essentially I was asking the wrong questions.
The problem statement should be: "How to filter a range NOT equal to multiple criterias?"
It is documented here: Explaination of why .autosort doesn't work with not equal to with multiple criterias.
Few Solutions were discussed:
Use another a column to help you determine the result you want to achieve. In my example, it would be looping through all values from
user input, and output true/false on another column based on
comparison, then filter that helper column to work around this
problem.
Filter with an impossible values, this is situational. For example, if you want to filter numbers, set up an outofbound criteria for
non-numbers like given in the explanation link above.
Write code to hide the already filtered criteria, and keep filtering what is left with rest of criteria, 2 at a time.
Use advanced filters
Hope this helps others who might get into same problems in the future.

Excel VBA - Find all rows with a specific value and get their row number

I have close to zero knowledge in excel and vba.
What I'm trying to do the the following:
for each row in ActiveSheet.ListObjects("SheetPotatoData")
if cell (column 5):(row) value equals "potato"
do something with (column 2):(row)
I would really appreciate it if you could enlighten me on the proper syntax to do this.
Thank you very much!
Look here: http://www.excel-easy.com/vba/range-object.html
For i = 1 To ActiveSheet.ListObjects("TableNameHere").ListRows.Count
If Cells(i,5).Value = "potato" Then
Cells(i,2).Value = "New value"
End If
Next
Alternatively, just add ".DataBodyRange.Rows" to the end of the first line in your line "For... Each" structure. You're asking VBA to iterate through each Row in a ListObject, rather each Row in the collection of Rows contained within the ListObject.
That allows sticking with the more elegant, readable, and reliable 'For...Each' structure rather than fetching range bounds and traversing it using counters. Using the DataBodyRange property of the list allows you to automatically handle any Header rows that may be present and not include them in your row inspection loop. You can reference the ListObject.Rows collection instead if you want Headers included.
Final code would look something like:
For Each row In ActiveSheet.ListObjects("SheetPotatoData").DataBodyRows.Rows
if row.Cells(1,5) = "potato"
'Do something
End If
Next

Copy cells if specific text is found

I seem to have a problem and currently have not found a solution to it, which is why I address this question to you:
Each day I have a list of invoices and orders coming from different suppliers, and the orders are based on part numbers and types.
This list is imported as text and then goes through a macro I made, to arrange everything in cells.
I also need to go through some steps to format this list based on the type of order (ex: windshield, carpets, wheels, etc ). what I usually do is to filter everything and select the order type that I am interested, and then copy on the same row cells with text and formulas from another worksheet, named "template", which is a list of conditions .
Since it varies from day to day, it may not necessarily contain all part types, which is I couldn't use a macro, and I have to continue by hand, and sometimes the list exceeds 200-300 lines.
To give you an example, if E2 has "windshield" I copy in M2 to Q2 a selection of cells from "Template" (M2 to Q2), if "carpets" I copy M3 to Q3, and so on. the list of conditions is around 15 - 20 rows, and sometimes 2 conditions may apply (if order exceeds $5000 I mark it red, if overdue I bold everything, etc) but mainly I copy based on text in coll E.
If this could be copied into a macro, I would really appreciate it, as I need to take some steps every time, like auto-fit, copy header, format the amounts as number (from text), change text color based on order type, etc, and this too takes time.
I hope this information is enough to make an idea about this, and if not, I could post an example of the list I have to work with.
Many thanks in advance for your support
Use Application.Worksheetfunction.Match to find in which row in Template the to-be-copied cells can be found, then copy range M-Q for this row and paste in your file
You are asking too much in one question to get help here. We are best at single issue questions. The text and code below is intended you give you some ideas. If your code does not work, post the relevant part here and explain the difference between what it does and what you want it to do.
The problems you mention do not sound difficult. I would expect basic VBA to be enough to get you started. Are you looking for bits of relevant code without learning VBA. If you are, this is a big mistake. Search the web for "Excel VBA tutorial" or visit a large library and review their Excel VBA Primers. There are many tutorials and books to choose from so select one that is right for you. The time spent learning the basics will quickly repay itself.
Dim RowCrnt As Long
Dim RowLast As Long
With Worksheets("xxxx")
RowLast = .Cells(Rows.Count,"E").End(xlUp).Row
For RowCrnt = 2 to RowLast
' Code to process each row goes here
Next
End With
The above is probably the structure of your code. The For loop will examine each row in turn which will allow you to take relevant actions.
I have used "E" as a column letter because your question suggests column "E" is the most important. However, code that references columns in this way can be very confusing. Worse, if the column positions change, you will have to work carefully through your code changing the column letters. Better to have some statements at the top like this:
Const ColDate As String = "A"
Const ColAmtInv As string = "B"
Const ColAmtPaid As string = "C"
Const ColProdType As String = "E"
With these constants every reference to a column uses a name not a letter. The code is easier to read and, if a column moves, one change to the constant statement will fix the problem.
The Select Case statement is useful:
Select Case .Cells(RowCrnt, ColProdType).Value
Case "carpets"
' code for carpets
Case "windshield"
' code for carpets
Case Else
' Unknown product type
.Cells(RowCrnt, ColProdType).Font.Color = RGB(255, 0, 0)
End Select
You can have a string of If statements so multiple actions can occur on a single row:
If DateAdd("m", 1, .Cells(RowCrnt,ColDate).Value) < Now() And _
.Cells(RowCrnt,ColAmtInv).Value) > .Cells(RowCrnt,ColAmtPaid).Value Then
' Invoice overdue
.Rows(RowCrnt).Font.Bold = True
End If
If .Cells(RowCrnt,ColAmtInv).Value) > 5000 Then
' Large invoice
.Rows(RowCrnt).Font.Color = RGB(255, 0, 0)
End If
You do not have to write the entire macro in one go. If most action is because of the product type then try that first.
Hope this helps get you started.

How to move one column to the end in Pivot table with VBA?

I create a pirvot table, but the colunm order is not what I wanted. I want to move one column to right end. I can do it in Excel, but don't know how to do it with VBA.
In Excel, can do in this way--active the column header which you want to move, click right-hand button, choose Move, Move "--" to end.
Record Macro--when record Macro, it just shows the exact position, just like,
ActiveSheet.PivotTables("PivotTable16").PivotFields("wk").PivotItems("#VALUE!") _
.Position = 12
But I want to use the Macro in other files, maybe the end position is not 12. Then the Macro can't be used.
Hope can get help here. How to do it to move the colunm to end by VBA? Thanks.
I hope I get you right.
You can get the end position by
ActiveSheet.PivotTables("PivotTable1").PivotFields("whatever").PivotItems.count
Basically it returns the number of items for a label
Edited
So you could do like
Dim total as Integer
total = ActiveSheet.PivotTables("PivotTable1").PivotFields("whatever").PivotItems.count
ActiveSheet.PivotTables("PivotTable1").PivotFields("whatever").PivotItems("whatever").position = total
Just a random note to anyone that comes across this and runs into the same issue I did. If in your macro you're hiding fields, it's going to give you an error. Don't use this code as the last thing you do when setting up your pivot table. Use this code, let it move to the bottom position, THEN have your code to hide your fields. If you hide fields first, it'll count the hidden fields then try to move it outside your pivot table and cause an error.

External Data Pull: Pull more specific data or change macro based on data

This question is somewhat difficult to explain, so bear with me.
I am pulling data from a large table for my company and am trying to create a macro to make this data easier to read/understand. The data that is on the site changes every day based on what caused certain failures in our plant, which causes my macro to analyze data that isn't there or wrong cells (due to rows getting shifted/moved/added/removed). Because I don't think that was really clear, here is an example:
The macro says to select cells J5, J13, and J25. These were, when I was creating the macro, the values I wanted to be put in a list. However, when I pulled the data and ran the macro today, these values were in different spots on my sheet (the value for cell J13 is now in J12). This completely messes up all of the analysis and renders my macro / data pull useless.
Is there a way to have the macro select the data more intelligently? Perhaps have it check for the group name, then select the value from the cell next to it? I wish I could word this better... Thanks if you've gotten this far!
Simply put... yes. Here's a code exert for looking for a groupname and getting the adjacent cell:
Dim Group1Range As Range
'Look in ThisWorkbook
With ThisWorkbook
'Look in Sheet1
With .Sheets(1)
'Look in Column I
With .Columns("I:I")
'Find the text Group1
Set Group1Range = .Find(What:="Group1").Offset(0, 1)
End With
End With
End With
'Indicate the address of the found range
Debug.Print Group1Range.Address
End Sub
Now here are ways that you can improve your question:
Explain how you know that cell J13 is no longer valid, and that J12 is now.
Give us some sample data.
Give us your code.
Tell us what your end result would be, possibly with an example.