excel vba sorting currency column descending - vba

I have a sheet with 2 columns A has shopnames and B has currency values
I want to sort in descending order column B
Here's what I have done:
With Sheets("helpsheet")
.Sort Key1:=Range("A"), Order1:=xlDescending, Header:=xlYes
End With
It doesn't work. What do I have to do differently?

There are some options of sorting available in VBA. The simplest way to improve you code is to add a range of data which you want to sort. Therefore you need to improve your code to the following:
With Sheets("helpsheet").Range("a1").CurrentRegion
.Sort Key1:=Range("B1"), Order1:=xlDescending, Header:=xlYes
End With
What I did:
assumed that your data range starts in Range("A1") and makes a region (therefore I used CurrentRegion property in With line.
I set sorting key to Range("B1") according to information from your question.
If required you could change these points accordingly to your situation.

Related

VBA Macros How to put in date order then numerical order?

Just as the title says, how can I put an excel sheet in date order, then numerical order? I know how to do these things separately, but the problem is, is that I need it to stay in date order and THEN be in numerical order. Once I put it in numerical order, the dates become mixed up again. The Date is in Column A while the data is in Column B.
Try,
with worksheets("sheet1")
.Cells.Sort Key1:=.Columns(1), Order1:=xlAscending, _
Key2:=.Columns(2), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlyes
end with
Use the Sort option from the Data menu

Copying rows from an Excel sheet to one in a different Excel file based on criteria [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'd like to start by telling you that I spent at least 2 hours reading different questions/answers on Stackoverflow and random google search results. I couldn't find an answer to my specific problem although a lot of questions/answers dealt with similar problems.
Every week, I'm manually copying rows from an Excel sheet into another Excel sheet based on certain criteria. In one column, the value of the cells that interest me are "not done" and in a second column I'm looking for due date that is in the past, i.e. overdue items. If both criteria are met, I copy the entire row into a newly created sheet in another Excel file.
I know VBA basics and thought about making my life easier by writing a macro that copies the respective rows into another Excel file and a new sheet. However, I'm not able to write a rather complex macro yet :(
Can you please help me by explaining how to write two loops (of some sort) that first look through the first column (find cells where value is not X) and after that look for a date in the past in a second column and then copy the rows where these two criteria met? Is that even possible with VBA? I'm not asking for the whole macro because I like to figure out how to get the remaining code right, but these loops are very complicated for a beginner and I'd really appreciate some guidance here.
Thanks in advance for taking the time to read this wall of text.
Edit: After checking excel-easy (thanks #maxhob17 ) I managed to make some progress. Please see this code so you get an idea of my progress. This code gets all the relevant rows based on the first criterion (status = done) and copies them into a new sheet in the same Excel file.
Public Sub Copy_Relevant_Items()
Dim CurrentWorkbook As Workbook
Dim InputWS As Worksheet
Dim OutputWS As Worksheet
Set CurrentWorkbook = Workbooks(ActiveWorkbook.Name)
Set InputWS = CurrentWorkbook.Sheets("Overview")
Set OutputWS = CurrentWorkbook.Sheets("Relevant")
Dim criterion As String
criterion = "Done"
Dim cells As range, cell As range
'Find the last used row in a Column: column C in this example
With InputWS
LastRow = .cells(.rows.Count, "C").End(xlUp).row
End With
Set cells = range("C2:C" & LastRow)
'Copy all the relevant rows into another sheet
For Each cell In cells
If cell.Value <> criterion Then
cell.EntireRow.Copy Destination:=OutputWS.range("A" & rows.Count).End(xlUp).Offset(1)
End If
Next cell
End Sub
you could use AutoFilter()
assuming your database spans from column A to D and dates are in column D then you could code
Option Explicit
Public Sub Copy_Relevant_Items()
Dim InputWS As Worksheet, OutputWS As Worksheet
Dim criterion As String
Set InputWS = ActiveWorkbook.Sheets("Overview")
Set OutputWS = ActiveWorkbook.Sheets("Relevant")
criterion = "Done"
With InputWS
With .Range("A1:D" & .cells(.Rows.Count, 1).End(xlUp).Row) '<--| reference its columns A to C from row 1 down to column A last not empty row. Change A and D to your actual data limit columns index
MsgBox .Address
.AutoFilter Field:=3, Criteria1:="<>" & criterion '<--| filter column C cells with content different from 'Criterion'. change "3" to your actual relative position of "status" column inside your database
.AutoFilter Field:=4, Criteria1:="<" & CLng(Date) '<--| filter column D cells with content less than current date. change "4" to your actual relative position of "date" column inside your database
If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then .Resize(.Rows.Count - 1).Offset(1).SpecialCells(xlCellTypeVisible).Copy Destination:=OutputWS.Range("A" & Rows.Count).End(xlUp).Offset(1) '<--| if any cell filtered other than headers then copy them to 'OutputWS'
End With
End With
End Sub

Creating muliple ranges based on criteria in column

New to VBA, and I'm trying to create multiple ranges or arrays based on a criteria in a column, then place those in a separate worksheet. The issue is that this code has to work for several different data sets. So one data sat will look something like
this, but with far more data points ( around 10,000 for each data set).
So what I'm trying to do is, for each group of 1's in the state column, create a range/array, then move the corresponding time and data in a new worksheet. So for the example I have, there would be 3 new worksheets, with the first new worksheet containing range("A2:B5"), the second one containing range("A10:B12"). With each data set, the state column changes and the number of new worksheets can also vary.
I have looked through this site, and the closest I have found to my needs is Creating Dynamic Range based on cell value, but it has a known number of ranges. I quite honestly have no idea how to accomplish what I need. I've been trying to make a while loop inside of a if then loop inside of a for each loop, but can't make it work.
Any help would be greatly appreciated! Been banging my head for hours now.
this should help you:
Option Explicit
Sub main()
Dim area As Range
With Sheets("myDataSheet") '<--| reference your sheet (change "myDataSheet") to your actual sheet name
With .Range("C1", .Cells(.Rows.Count, "A").End(xlUp)) '<--| reference its columns A:C range form row 1 down to last column A not empty row
.AutoFilter Field:=3, Criteria1:="1" '<--| filter referenced range on its 3rd column (i.e. "State") with 1
If Application.WorksheetFunction.Subtotal(103, .Resize(, 1)) > 1 Then '<--| if any filterd cells other than header
For Each area In .Resize(.Rows.Count - 1, 2).Offset(1).SpecialCells(xlCellTypeVisible).Areas '<--| loop through filtered range (skipping header) 'Areas'
area.Copy Sheets.Add(Sheets(Sheets.Count)).Range("A1") '<--| copy current 'Area' into new sheet
Next area
End If
End With
.AutoFilterMode = False
End With
End Sub

Sort multiple columns by one column

I'm making an email list in Excel with three columns. On the worksheet, I have two buttons, "sort by Name" and "sort by Date added". I would like to sort all three columns by the button chosen so I can find entries faster (I am also entering a separate lookup function later).
Basically, I want the sort function that's already on the toolbar in the worksheet where you can just press it and it knows which column to sort by already. I've seen things for macros and for VBA but all of them are sorting columns by separate parameters, whereas I need these columns linked.
The code produce by the recorder on a Range.Sort method is very verbose and can be chopped down quite a bit to what is essential.
If columns A:C were Name, Email, Date Added then this will sort by Name first, then Date Added.
with worksheets("sheet1") '<~~ set this properly!
with .cells(1, 1).currentregion '<~~ assumes data starts in A2 with a header row in A1:C1
.Cells.Sort Key1:=.Columns(1), Order1:=xlAscending, _
Key2:=.Columns(3), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
end with
end with
This will sort by Date Added first, then Name.
with worksheets("sheet1") '<~~ set this properly!
with .cells(1, 1).currentregion '<~~ assumes data starts in A2 with a header row in A1:C1
.Cells.Sort Key1:=.Columns(3), Order1:=xlAscending, _
Key2:=.Columns(1), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
end with
end with
You can have up to 3 keys. Any more than that and you have to run the routine twice. The opposite of xlAscending is of course xlDescending.
The best way I've found to find something that's already on the toolbar is to use the "Macro Recorder" in a blank/new workbook, and then look at the code.
Are the columns adjacent to each other? Because if so you can use something like this;
//Alright, so this is if you wanted each of the columns to have their
//own values that you are sorting by, if you just want one criteria,
//just use one of the lines
Dim varName as String
Dim varDate as String
Dim varExtra as String
ActiveSheet.Range("A:C").AutoFilter Field:=1, Criteria1:=varName
ActiveSheet.Range("A:C").AutoFilter Field:=2, Criteria1:=varDate
ActiveSheet.Range("A:C").AutoFilter Field:=3, Criteria1:=varExtra
Basically, it's saying for the three columns given, go find the field (which will correspond to a column) indicated and filter by the criteria. You can also use a string value in the Criteria spot instead of a variable.

Compare worksheets and insert new rows

I currently have two sheets with six columns of data, both in the same format, except that Sheet 1 has historic data and sheet 2 has newer data with some additional rows. Both sheets are sorted in order of the contents in the 2nd column followed by the 4th column.
I want to prepare a macro that compares both sheets and looks down the 2nd and 4th columns to identify the new rows in Sheet 2 that are not in Sheet 1 and color highlight these rows in Sheet 2. In addition, I would like the new rows from sheet 2 to be inserted into Sheet 1 in the correct order.
For Example
The reason for doing all this as opposed to just copying the entire contents of Sheet 2 into Sheet 1 is because sheet 1 has a number of formulas beyond the 6 columns which reference certain blocks of cells and it is require that these references be preserved. I currently have to manually insert each new row and given the amount of data being processed, this takes quite some time. I have tried adapting other macros that I found across the internet to perform this task but they don’t quite work.
Step #1: identify rows that are in sheet2 and not in sheet1
Create a new column E in both sheets with this formula:
=B2&D2
(starting from row 2 and auto fill it to the entire column)
in sheet2 create column F with this formula
=ISERR(VLOOKUP(Sheet2!E2,Sheet1!E:E,1,FALSE))
Now column F would be TRUE only for rows that aren't in sheet1.
Next you'll need to add conditional formatting for F=TRUE
Step #2: Copy the missing data
Filter rows from sheet2 with F=TRUE
Copy them to the end of sheet1
Sort sheet1
If you copy the data (excluding the header) from Sheet2 underneath the data in Sheet1 and subsequently a) remove duplicates then b) sort on columns B and D, you should achieve the results you are looking for.
Sub collect_and_sort()
With Sheets("sheet1")
Sheets("sheet2").Cells(1, 1).CurrentRegion.Offset(1, 0).Copy _
Destination:=.Cells(Rows.Count, 2).End(xlUp).Offset(1, -1)
With .Cells(1, 1).CurrentRegion
.RemoveDuplicates Columns:=Array(2, 4), Header:=xlYes
.Cells.Sort Key1:=.Columns(2), Order1:=xlAscending, _
Key2:=.Columns(4), Order2:=xlAscending, _
Orientation:=xlTopToBottom, Header:=xlYes
End With
End With
End Sub
From the data on two sheets like this (shown on one sheet for space considerations),
    
You will have this after the macro has run.
    
I will admit I am unclear on whether the 3000/b in Sheet1!B11:D11 was a typo or an actual duplicate record. The macro does reproduce your desired results.