Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Copy to Excel file
Message
From
19/04/2001 04:36:30
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00497057
Message ID:
00497142
Views:
9
This message has been marked as the solution to the initial question of the thread.
>I think I may have put this out there before. If so, please forgive me.
>
>I am copy data to an Excel file on a regular basis. As you know, there is a limit to how many rows you can copy to an excel file in VFP 6.0. Is there some clever way to get around this?
>
>Thanks in advance for you help.
>
>
>Randall

Randall,
Depends on how many rows you'd transfer and if more than MaxRows (current 65535+1 for header) how you want extra sheets (separate workbooks acceptable or not).
I say depends because speed is very important since VBA is awfully slow. My general rule of thumb with OLE automation is 'do as much as you can on VFP side and only those you can't on OLE side'.
If lte MaxRows then it's easy and fast :
-copy to ... type fox2x or delimited (type csv is essentially same except it adds a header line listing fieldnames)
-open in excel dbf or txt you copied

If gt Maxrows then you should decide whether you would add new sheets or show in multipl tiled workbooks. If new workbooks approach is acceptable it's about 4-5 times faster than adding new sheets.

Here is sample code doing it the slow way with new sheets added :
Clear all
* Create a test cursor
Create cursor testcursor (Rcno i,cType c(10), nType i, dType d)
Rand(-1)
For ix = 1 to 200000 && Create 200000 recs cursor
  Insert into testcursor values ;
    (recco()+1,sys(2015), int(rand()*1000), date()-int(rand()*100))
Endfor
Set sysformats on
Set safety off

lnTotal = reccount()
Wait window nowait "Pls wait sending data to Excel..."
Start = seconds()
oExcel = createobject("Excel.application")

With oExcel
  .workbooks.add && Add a new workbook
  lnMaxRows = .ActiveWorkBook.ActiveSheet.Rows.Count && Get max row count
  .ActiveWorkBook.Close(.f.) && Close no save
  lnNeededSheets = ceiling( lnTotal / lnMaxRows ) && 1 row header
  ? "Total Pages : "+padr(lnNeededSheets,3," ")
  lcFirstPage = 'Page001'
  Copy to (lcFirstPage) for recno()<=lnMaxRows-1 type fox2x && One for header
  .workbooks.open(sys(5)+curdir()+lcFirstPage+".dbf") && Open saved
  ? "Page no :   1/"+;
    padr(lnNeededSheets,3," ")+ ;
    "   Elapsed : ",seconds() - start
  If lnNeededSheets > 1
    With .ActiveWorkBook
      lnCurrentSheetCount = .sheets.count
      If lnNeededSheets > lnCurrentSheetCount
        .sheets.add(,.sheets(lnCurrentSheetCount),;
          lnNeededSheets - lnCurrentSheetCount) && Add new sheets after old ones
      Endif
      For ix = 2 to lnNeededSheets
        With .sheets.item(ix)
          .name = "Page "+padl(ix,3,"0")
          .activate
          =InsertGroup(ix, lnMaxRows)
        Endwith
      Endfor
      .sheets.item(1).activate
    Endwith
  Endif
  .visible = .t.
Endwith
? "Total Elapsed : ",seconds() - start

Function InsertGroup
  Lparameters tnSheetNumber, tnMaxRows
  Local lnPasteStart, lcTempFile
  lnPasteStart = ( tnSheetNumber - 1 ) * tnMaxRows
  lcTempFile = sys(2015)+".txt"
  Copy to (lcTempFile) delimited with TAB for between(recno(),lnPasteStart,lnPasteStart+tnMaxRows)
  _Cliptext = filetostr(lcTempFile)
  Erase (lcTempFile)
  With oExcel
    .workbooks(1).sheets.Item(tnSheetNumber).activate
    .workbooks(1).ActiveSheet.Range("A1").PasteSpecial()
    _Cliptext = "" && Empty clipboard
    ? "Pasted from ", lnPasteStart,' to ',min(lnPasteStart+tnMaxRows-1, reccount()), "elapsed", seconds() - start
  Endwith

  ? "Page no : "+;
    padl(tnSheetNumber,3," ")+;
    "/"+;
    padr(lnNeededSheets,3," ")+ ;
    "   Elapsed : ",seconds() - start
New workbooks approach changes code slightly :
Wait window nowait "Pls wait sending data to Excel..."
Start = seconds()
oExcel = createobject("Excel.application")
#Define xlNormal  -4143
#Define xlTiled  1
With oExcel
  .workbooks.add && Add a new workbook
  lnMaxRows = .ActiveWorkBook.ActiveSheet.Rows.Count && Get max row count
  .ActiveWorkBook.Close(.f.) && Close no save
  lnNeededBooks = ceiling( lnTotal / (lnMaxRows - 1) ) && 1 row header
  ? "Total Books : "+padr(lnNeededBooks,3," ")
  For ix = lnNeededBooks to 1 step - 1 
  && Do a reverse pass so we wouldn't need an extra command to arrange windows 
    lnStart = ( ix - 1 ) * (lnMaxRows-1) + 1
    lcDBFName = "temp"+padl(ix,2,"0")+".dbf"
    Copy to (lcDBFName) ;
      for between(recno(),lnStart,lnStart+lnMaxRows-2) ;
      type fox2x
    .workbooks.Open(sys(5)+curdir()+lcDBFName)
    .ActiveWindow.WindowState = xlNormal
    ? "Book no : "+;
      padl(ix,3," ")+;
      "/"+;
      padr(lnNeededBooks,3," ")+ ;
      "   Elapsed : ",seconds() - start
  Endfor
  .Windows.Arrange(xlTiled)
  .visible = .t.
Endwith
? "Total Elapsed : ",seconds() - start
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Reply
Map
View

Click here to load this message in the networking platform