1

We have a small Book Club. We read the book and then score it.
To keep track of the books I use a macro that takes the scores adds the latest book and then sorts the list from highest to lowest points.
I have to manually update the fields with each new book.

I tried to automate the process recently by using:
Meaning of .Cells(.Rows.Count,“A”).End(xlUp).row which counts the number of empty cells upwards until it reaches a cell with some data in it and then performs the operation on it.
The modified macro works until it tries to sort the list and it then stops working.

How I can modify the sort?

This is the Book Club file: Page 1.
enter image description here

This is the Book Club file: Page 2.
enter image description here

This is the modified macro which works until the sort then stops.

Sub PositionIndex()
 '
' PositionIndex Macro
' This macro sorts the ongoing position of the most popular books.
'
' Keyboard Shortcut: Ctrl+Shift+X

Dim wb As Workbook
Dim ws As Worksheet
Dim symbol As String
Dim n As Integer
Dim lastrow As Long

Sheets("Position Series").Select
Find the last used row in a Column: column K in this example

    With ActiveSheet
        lastrow = .Cells(.Rows.Count, "K").End(xlUp).Row
    End With
    
    MsgBox lastrow
       
    Dim DataRange As Range

    Set DataRange = Range("C7:K" & lastrow)
    DataRange.Select
    Selection.ClearContents
 
    Sheets("Time Series").Select
    'Find the last used row in a Column: column "Q" in this example
    
     With ActiveSheet
        lastrow = .Cells(.Rows.Count, "Q").End(xlUp).Row
    End With
    
    MsgBox lastrow
    
    Range("Q9:Q" & lastrow).Select
    Selection.Copy
    
    Sheets("Position Series").Select
    Range("K7").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
        
    Sheets("Time Series").Select
    'Find the last used row in a Column: column "I" in this example
    
     With ActiveSheet
        lastrow = .Cells(.Rows.Count, "I").End(xlUp).Row
    End With
    
    MsgBox lastrow
    
    Range("C9:I" & lastrow).Select
    Selection.Copy
    Sheets("Position Series").Select
    Range("C7").Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    
    Sheets("Position Series").Select

    With ActiveSheet
        lastrow = .Cells(.Rows.Count, "K").End(xlUp).Row
    End With
    
    MsgBox lastrow
    
    Range("C7:K" & lastrow).Select
    Application.CutCopyMode = False
    ActiveWorkbook.Worksheets("Position Series").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Position Series").Sort.SortFields.Add Key:=Range( _
        "K7:K" & lastrow), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
        xlSortNormal
    With ActiveWorkbook.Worksheets("Position Series").Sort
        .SetRange = Range("C7:K" & lastrow).Select
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    Range("A2").Select
    Sheets("Time Series").Select
    Range("A2").Select
    
End Sub
Community
  • 1
  • 1
Terry
  • 13
  • 4
  • Exactly what happens when it "stops" ? – Tim Williams Jun 26 '20 at 16:15
  • I would just have a data sheet where the list of books is recorded and added to - which means it can stay in time order. Then an output sheet based on large() and index() which will always be in highest to lowest order, I would also use iferror() so that the output sheet shows blanks instead of errors. No macro to go wrong. – Solar Mike Jun 26 '20 at 19:23
  • The Macro will run OK until it reaches the line: .SetRange = Range(“C7 :K” & lastrow).select It then stops with: Run-Time Error ‘438’: Object doesn’t support this property or method – Terry Jun 27 '20 at 08:34

1 Answers1

0

I really really like this little project you have :)! I took some time and rewrote the code so you can see what is happening and how it can be a bit more stable and efficient.

I think I understand what you want to achieve.

1 . - You want to define the range (column K) where the rankings are:

ActiveWorkbook.Worksheets("Position Series").Sort.SortFields.Add Key:=Range( _
        "K7:K" & lastrow), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:= _
        xlSortNormal

2 . - And then sort the columns to the right (Date, Title, Author, Proposer) of the defined range.

With ActiveWorkbook.Worksheets("Position Series").Sort
        .SetRange = Range("C7:K" & lastrow).Select
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
End With

These two parts can be rewritten as:

   Postion_Series.Range("C7:K" & lastrow).Sort key1:=Range("K7:K" & lastrow), _
   order1:=xlDescending, Header:=xlNo

I see you have several of the following lines:

Sheets("Position Series").Select

And you don't need that.

So first we define your worksheets:

Dim Time_Series As Worksheet
Dim Postion_Series As Worksheet
Set Time_Series = ActiveWorkbook.Worksheets("Time Series")
Set Postion_Series = ActiveWorkbook.Worksheets("Position Series")

So every time we use the variable Time_Series we are referring to the excel sheet "Time Series". Therefore we can rewrite the code:

Sheets("Position Series").Select
'Find the last used row in a Column: column K in this example

    With ActiveSheet
        lastrow = .Cells(.Rows.Count, "K").End(xlUp).Row
    End With

To a more stable and efficient code, because you always want in this part the ActiveSheet to be the "Postion Series" worksheet, and we can call our variable Postion_Series for that:

With Postion_Series
    lastrow = .Cells(.Rows.Count, "K").End(xlUp).Row
End With

What is happening is that we are telling your code that your line of code should be applied to the variable Postion_Series = as saying "direct me to the worksheet "Position Series" and execute the code" i.e. Sheets("Position Series").Select.


Full Revised Code:

Sub PositionIndex()
 '
' PositionIndex Macro
' This macro sorts the ongoing position of the most popular books.
'
' Keyboard Shortcut: Ctrl+Shift+X

Dim wb As Workbook
Dim Time_Series As Worksheet
Dim Position_Series As Worksheet
Dim symbol As String
Dim n As Integer
Dim lastrow As Long

Set Time_Series = ActiveWorkbook.Worksheets("Time Series") 'Define the worksheet "Time Series" to a variable
Set Position_Series = ActiveWorkbook.Worksheets("Position Series") 'Define the worksheet "Position Series" to a variable

'Find the last used row in a Column: column K in this example
    With Position_Series
        lastrow = .Cells(.Rows.Count, "K").End(xlUp).Row 'Find the last row for Column K in the worksheet "Position Series"
    End With
    
    MsgBox lastrow
       
    Dim DataRange As Range

    Set DataRange = Position_Series.Range("C7:K" & lastrow + 50) 'Define the datarange in the Sheet "Position Series" to clear the old data
    DataRange.ClearContents 'Clear the data for the defined range
 
'Find the last used row in a Column: column "Q" in this example
    With Time_Series
        lastrow = .Cells(.Rows.Count, "Q").End(xlUp).Row 'Find the last row for Column Q in the worksheet "Time Series"
    End With
    
    MsgBox lastrow
    
    'Copy column with Score rankings (column Q) from worksheet "Time Series" and paste it to "Position Series" for the column K, "Position"
    Time_Series.Range("Q9:Q" & lastrow).Copy 'Copy column until the last value
    'Paste the column to the new place
    Position_Series.Range("K7").PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    
    'Find the last used row in a Column: column "I" in this example
     With Time_Series
        lastrow = .Cells(.Rows.Count, "I").End(xlUp).Row 'Find the last row for Column I in the worksheet "Time Series"
    End With
    
    
    MsgBox lastrow
    'Copy relevant data about the Date, Title, Author, Propser for from the "Time Series" to the "Position Series"
    Time_Series.Range("C9:I" & lastrow).Copy
    'Paste it to the new place
    Position_Series.Range("C7").PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False 'This line will deselect the copy range. I think you should move to hear to deselect the copy range as soon you have pasting your data. So I moved the line to here.
    
    'Find the last row for Column K to decide which row to sort
    With Position_Series
        lastrow = .Cells(.Rows.Count, "K").End(xlUp).Row
        MsgBox lastrow
    End With

    Position_Series.Activate    
        'Sort the range "Range("C7:K" & lastrow)" by the values of column K. From Largest to Smallest, and the first row is not header.
        Position_Series.Range("C7:K" & lastrow).Sort key1:=Position_Series.Range("K7:K" & lastrow), _
        order1:=xlDescending, Header:=xlNo
    
End Sub
Wizhi
  • 6,424
  • 4
  • 25
  • 47
  • Hi Wizhi, many many thanks for your efforts. i am going to download the new code that you wrote and get it into the macro, and then take it for a 'test drive'. I will get back to you in a couple of days with the results. Terry – Terry Jun 29 '20 at 14:44
  • Hi Terry!. Please do that :). If you encounter any issues or have any questions, feel free to ask!! :) – Wizhi Jun 29 '20 at 17:19
  • Hi Wizhi. OK....Ran the code, but the macro still will not sort. It runs all the way through and stops at this line. Postion_Series.Range("C7:K" & lastrow).Sort key1:=Range("K7:K" & lastrow), _ order1:=xlDescending, Header:=xlNo. It has an Run-Time error code of 1004. – Terry Jun 30 '20 at 05:34
  • Hi Terry!, Yes, because I missed a to say which sheet it should look into when it sort the position. `Sort key1:=Range("K7:K" & lastrow)` -> `Sort key1:=Position_Series.Range("K7:K" & lastrow)`. Also did some other minor updates of the code. I also found an old thread where you kindly gave an example of your workbook. So I used that, I have tested the code and filled in with missing data. You can find a copy [here](https://www.dropbox.com/s/ipdgtd3jepbwe6g/book%20clubmacro2.xlsm?dl=0). I really hope it works this time, otherwise let me know. It's a beautiful project you have made :)!!! – Wizhi Jun 30 '20 at 16:25
  • 1
    Hi Wizhi, Sorry it still will not sort. It stops at this line. Postion_Series.Range("C7:K" & lastrow).Sort key1:=Position_Series.Range("K7:K" & lastrow), _ order1:=xlDescending, Header:=xlNo. With a code of '424'. Sorry to take up so much of your time. – Terry Jul 01 '20 at 06:32
  • No worries. I'm just so puzzled it doesn't work for you :(. Have you even tried the file? I also updated the code in the end a little bit. Do you use Excel 2016 or 365 or maybe 2010? Start to wonder if there are some version issues. – Wizhi Jul 01 '20 at 18:20
  • 1
    Hi Wizhi...Success!!!! . You my friend are a genius. I changed my code for yours and 'Boom' up it came. I guess that I must have had a glitch in my code which stopped it from performing the final sort. The Book Club will never know how useful your input has been as they have no interest in the program, but they love to chew over the stats of the books that we have read. How many books, who has the highest scores, whats the most popular book in any year, etc, etc. But I'll know how much help you've been. As I am new to the website I don't know how to award points for assistance. Many thanks.. – Terry Jul 02 '20 at 08:03
  • I got a lot of inspiration from you and your work and I love to help people that have this kind of projects. I love stats by myself and it somewhat tedious to copy/paste information to get the stats. Just feel free to ask more question here at SO. Me plus other will help you. Feel free to mark the question as answer (grey tick mark below voting buttons, link for [picture](https://meta.stackoverflow.com/questions/251078/how-to-update-and-accept-answers)) if you think the answer solved your problem. It will help other to see the question is solved and gives you and me some points. – Wizhi Jul 03 '20 at 15:38
  • Good luck Terry!!, it was really fun to help you and thanks for your patience. Sometimes code can be tricky to work out, only a space or an extra character can mess it up :(. But I'm really happy that you got to work it out! I hope you come up with more statistic sheets, I think the book club will love that ;). So my book recommendation.. Think it gotta be: "One Hundred Years of Solitude - Garcia Marques". Best wishes //Jonathan – Wizhi Jul 03 '20 at 15:40
  • 1
    Thanks once again Jonathan. I intend to stay with the website and try to improve my coding skills. If you get to France I would love to buy you a beer (or two). Thanks also for your book choice. Take care. – Terry Jul 04 '20 at 07:19
  • Thank you Terry! Wish you the best and If I have my ways from Sweden to France it would be nice to say hi :). If you have any coding questions in the future, just let me know. Happy coding and take care :)!!! – Wizhi Jul 04 '20 at 10:57
  • Hi Wizhi, Yes.....that would be great. Please do. Incidentally, I am trying to find some coding that would download stock market prices both European and the USA, and get it into spreadsheet. Would you happen to know of anywhere that I could look to find such coding? – Terry Jul 05 '20 at 06:25
  • Actually I do some of that stuff today ;). Is quite tricky and a lot of patience as the source sites (yahoo finance, google finance) changes the format/web sites. But there are some different sources I have used for that projects. [PortfolioSlicer](http://www.portfolioslicer.com/download.html), and a lot of googling vba codes, for example: [Scraping data with vba from Yahoo finance](https://stackoverflow.com/questions/49510545/scraping-data-with-vba-from-yahoo-finance), [Multiple Stock Quote Downloader for Excel](http://investexcel.net/multiple-stock-quote-downloader-for-excel/) – Wizhi Jul 05 '20 at 21:37
  • [Open Source Excel VBA macro for downloading Stock Quotes from Yahoo Finance](https://www.spreadsheetml.com/technicalindicators/opensourcestockquotesdownload.shtml), [How to download data from Yahoo finance limited to 100 rows](https://stackoverflow.com/questions/57664229/how-to-download-data-from-yahoo-finance-limited-to-100-rows). I would suggest you to try some code and post code and clear questions when you get stuck. There are some very good people with huge knowledge in this area. It's tricky but a really fun way to learn coding :)!! – Wizhi Jul 05 '20 at 21:37