I have a table in Excel with a list of names linked with some data. I would like to be able to create new rows (with data from something form-alike) and have them sorted into the existing rows.
I don't really know how to code VBA in Excel and can't find any examples that insert rows based on their data. Most examples insert new blank rows to style the table.
I've got this to insert the new row with input value of user:
Sub Test_Function()
Dim val As String
val = InputBox("Enter your name", "May I know your Name!")
'Inserting a Row at at Row 2
Range("A3").EntireRow.Insert
Range("A3").Formula = val
'
End Sub
More information: The data is in this lay-out:
Name - Money Provided W1 - Money ProvidedW2 - Drinks W1 - Drinks W2 - Total Money owed
When entering a new name, the row needs to copy the formulas like the other rows. At the bottom of the sheet is another row with the sum of 'money provided' and 'money owed'. (I think therefore I can't just add it to the last row, but rather insert a new one, not sure tho...)
I wouldn't insert a new row, but rather put the results of the insertion at the end of the sheet:
lastRow = Range("A1").End(xlDown).Row + 1
Range("A" & lastRow) = data1
Range("B" & lastRow) = data2 'etc.
and then sorting the whole sheet by the key you prefer (this example is for sorting A-C in descending order by column A - recorded macro):
Columns("A:C").Select
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A1:A" & lastRow), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
.SetRange Range("A1:C" & lastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Related
I have VBA code that uses the columns (values in the Rows section) of a Pivot table on one worksheet to sort another worksheet's data and then summarize that data. Whenever the Pivot table changes the summarized data is recalculated by users pushing a command button. After I run the AutoFilter.Sort.SortFields.Clear I'm still getting 13 sorts exist. These are combinations of the previous sorts. This continues to build up until I get a XLSM file is corrupt message.
Function SortTab(pSheet As String, pCol As String) As Boolean
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sort entire tab by 1 to 5 columns
'
'Code examples from recording a Macro when sorting
' ActiveWorkbook.Worksheets("Data").AutoFilter.Sort.SortFields.Add Key:=Range("I2:I1019"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
' ActiveWorkbook.Worksheets("Data").AutoFilter.Sort.SortFields.Add Key:=Range("J2:J1019"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
'
'Parameters:
' pSheet Sheet to find range Example: Data
' pCol Last column on sheet Example: BC100
'
'Global Variables:
' gRange UsedRange for current sheet Example: A1:BC100
' gPivotCols Array of column names to Sort Example: gPivotCols(1) = 5 for "Dept", gPivotCols(2) = 4 for "Company"
' gColSort Last column in the sort Example: 4 for the Company column being the 4th column in the data sheet
'gColMax Max # of Sort Columns is 5
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error GoTo Err_SortTab
Dim i As Integer
'Remove all Fiters & Sorts
Worksheets(pSheet).Activate 'Select sheet
Worksheets(pSheet).AutoFilterMode = False 'Turn AutoFilter off
Worksheets(pSheet).UsedRange.AutoFilter 'Turn AutoFilter on
Worksheets(pSheet).AutoFilter.Sort.SortFields.Clear 'Clear any Sorts
'Code inserted to find out how many sort columns exist after a AutoFilter.Sort.SortFields.Clear
'Currently returning a value of 13 sorts
i = ExistingSorts()
If i > 0 Then
MsgBox i & " existing sorts still exist", vbCritical, "Error"
SortTab = False
Exit Function
End If
With ActiveSheet.Sort
.Header = xlYes 'Tab has Headers
.MatchCase = False 'Not case sensitive
.Orientation = xlTopToBottom 'Sort Top to Bottom
.SetRange Range(gRange) 'Complete range on Data tab to sort example: A1:BC100
For i = 1 To gColMax 'Loop throuh column heading in the Pivot table
If gPivotCols(i) = 0 Then 'Check for less than 5 columns
Exit For
End If
gColSort = gPivotCols(i) 'Set the last column in the Sort
.SortFields.Add Key:=Range(gRange).Columns(gColSort), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal 'Add sort column
Next i
.Apply
End With
Exit_SortTab:
SortTab = True
Exit Function
Err_SortTab:
If Application.UserName = "Murf" Then
MsgBox Err.Description, vbOKOnly, "Error #: " & Err.Number
Stop
Resume
End If
End Function
Function ExistingSorts() As Integer
'''''''''''''''''''''''''''''''''''''''''''''''''''
' Copied from internet
' Count existing sorts
'''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
Dim S As Sort
Dim SF As SortField
Set S = ActiveSheet.Sort
ExistingSorts = S.SortFields.Count
End Function
I've tried several different variations of
Worksheets(pSheet).AutoFilter.Sort.SortFields.Clear
Activesheet.AutoFilter.Sort.SortFields.Clear
with Activesheet
.AutoFilter.Sort.SortFields.Clear
The manual sorts created on the data tab disappear (arrows go away) but the actual data is sorted by whatever string of columns is already entered.
Just interrupting with a small sorting problem I have with a table:
I have a table in which I list some European government bonds:
Only the ISIN is necessary: COUNTRY and MATURITY are retrieved from a Bloomberg API
Say Italy issue a new BOND with Isin code : IT0005402117
I tried a VBA Macro that insert a new line with ISIN = IT0005402117
Then sort the table by 1st: COUNTRY, then 2nd: MATURITY
Here's the code:
Private Sub ButtonAddBondOK_Click()
FormAddBond.Hide
Dim Isin As String
'Declare Table
Dim MyTable As ListObject
Set MyTable = Range("BondBase").ListObject
Isin = FormAddBond.TextBoxIsin.Value
'Test that Isin doesn't exists
Dim r As Range, IsItThere As Range
Set r = MyTable.Range
Set IsItThere = r.Find(What:=Isin, After:=r(1))
If Not IsItThere Is Nothing Then
MsgBox "ISIN already exist, please check."
'Cleaning form
Unload FormAddBond
Exit Sub
End If
'Inserting new row
Dim NewRow As ListRow
Dim IsinCol, FutCol As Long
IsinCol = MyTable.ListColumns("Isin").Range.Column
Set NewRow = MyTable.ListRows.Add(AlwaysInsert:=True)
With NewRow
.Range(IsinCol).Value = Isin
End With
'waiting 3 seconds
Application.Wait (Now + TimeValue("0:00:03"))
'Sorting Table
With MyTable.Sort
.SortFields.Clear
.SortFields.Add Key:=Range("BondBase[[#ALL],[COUNTRY]]"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SortFields.Add Key:=Range("BondBase[[#ALL],[MATURITY]]"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortTextAsNumbers
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
'Cleaning form
Unload FormAddBond
End Sub
After running the code, the row is properly insert and table is properly sorted, BUT for the new row that appears at the top. this even though I added a 3 seconds wait for Bloomberg API to retrieve the values...
Result:
Any clue what I have done wrong please?
The following code below execute fine but the output of the sort function is a mess.
Intention of code is to sort range of values from B2 to last row of L
According to DD/MM/YYYY HH:MM:SS value
Code is used to sort a series of files in a folder, so a simple macro recording won't suffice
Dim Slrow As Long
'Updated last row count to Column B from comment made
Slrow = Cells(Rows.Count, 2).End(xlUp).Row
Range("B2:L" & Slrow).Sort Key1:=Range("B2:L" & Slrow), Order1:=xlAscending, Header:=xlNo
SortWb.Close SaveChanges:=True
Output of Code
File Download link available below ->
Download
Sorting with Custom Sort
The problem is the Key and the range where you apply it, and also the options (looks like your data got headers in row 1). Try something like this:
Range("B1:L" & Slrow).Sort Range("B2:B" & Slrow), xlAscending, , , , , , xlYes, , False, xlSortColumns, xlPinYin, xlSortNormal
Change the Key1 to the column you want to sort at eg Key1:=Range("B1").
use SortOn:=xlSortOnValues to make sure it sorts on the values not text (I think this does the trick here).
make it recognize headers automatically by using Header:=xlYes (easier).
This should work:
Dim ws As Worksheet
Set ws = ActiveSheet 'better specify Worksheets("SheetName")
With ws.Sort
.SortFields.Clear
.SortFields.Add2 Key:=ws.Range("B1"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
.SetRange ws.Range("B1:L" & Slrow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
If it doesn't work your dates are no date values but text and you need to convert them into date values.
Also it might be a good idea always to use the ISO date format YYYY-MM-DD hh:mm:ss which is the only one that can not be misunderstood by humans and can easily be sorted even as text (eg in file names etc).
Example how it looks sorted with the code above:
I am new to VBA, and excel macros, but not basic programming. I have a few dozen excel files, that I am taking data from, cleaning it, and populating it into one file. After the data is populated, I'd like to sort it according to Column A. After an 2 hours of playing with it, I just recorded a macro and cut and pasted it into my ButtonCall sub. But I'd like to know why its working and why the solutions I found here, and online would not work for me...
Why does this simple code NOT work:
Set q = ThisWorkbook.Worksheets(2)
LastRow = q.UsedRange.rows.Count 'q.UsedRange.Row ' - 1 + q.UsedRange.rows.Count
LastCol = q.UsedRange.Columns.Count
q.Range("A6:AAA" & LastRow).Sort Key:=q.Columns("A"), Order:=xlDescending
While this modified recorded Macro does?
Set q = ThisWorkbook.Worksheets(2)
LastRow = q.UsedRange.rows.Count 'q.UsedRange.Row ' - 1 + q.UsedRange.rows.Count
LastCol = q.UsedRange.Columns.Count
q.Sort.SortFields.Clear
q.Sort.SortFields.Add Key:=Range("A6:A" & LastRow), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With q.Sort
.SetRange Range("A6:AAA" & LastRow)
.Header = xlGuess
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
Any thoughts? Thanks.
Your code is using the range.sort method, while the original code is employing the sort object - two different things.
This code will sort "A6" to end of data by column A, using the Range.Sort method.
Sub MySort()
Dim q As Worksheet
Dim r As Range
Set q = ThisWorkbook.Worksheets(2)
' specify data range from "A6" to end of data
Set r = q.Range("A6", q.Cells.SpecialCells(xlCellTypeLastCell))
' Header:=xlNo assumes A6 row is included in data to be sorted
r.Sort key1:=r(1, 1), Order1:=xlDescending, Header:=xlNo
End Sub
How to sort rows by a column containing numbers in ascending or descending order?
I know how to sort using Filters and Using Sort function in VBA. But it sorts in alphabetical order only not by numbers.
This is so far I have done.But still the sorting is coming alphabetically.
Sub sortdata()
Dim LastRow As Integer
NoOfRows = Sheets("RawData").Range("A" & Rows.Count).End(xlUp).Row
Sheets("RawData").Rows("2:" & NoOfRows).NumberFormat = "0"
Sheets("RawData").Sort.SortFields.Add Key:=Range("A1"), _
SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Sheets("RawData").Sort
.SetRange Range("A1:B" & NoOfRows)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
I prefer the Range.Sort method:
[EDIT 2]:
I have added the .TextToColumns line to programmatically address the numbers stored as text issue
Sub sortdata()
Dim ws As Worksheet
Set ws = Sheets("RawData")
With ws.Range("A1:B" & ws.Cells(Rows.Count, "A").End(xlUp).Row)
Intersect(.Cells, ws.Columns("A")).TextToColumns
.Sort Intersect(.Cells, ws.Columns("A")), xlAscending, Header:=xlGuess
End With
End Sub
[EDIT]:
After reading asker's comment:
I will provide an example . If the column A contains this
values:1,2,55,12,14,5343,22222,9 Then after sorting using filter or
inbuilt sort method. The values are sorted as
follows:1,12,14,2,22222,5343,9. But I need the result as follows:
1,2,9,12,14,5334,22222. Is there any in-built function for this?
The problem is that your numbers are stored as text. You'll need to convert them to numbers.
Select column A -> Data -> Text to Columns -> Finish
Now the numbers should sort correctly.