* Now we want to get these on 3 sheets * Sheet1: Employees only * Sheet2: Customers only * Sheet3: Orders, ordItems, Products layed out horizontally OPEN DATABASE myProductionDatabase SELECT cClient_Account_Number, CAST(CHRTRAN(mNotes, CHR(13) + CHR(10), CHR(10)) as M) as Notes ; FROM Trans WHERE tDate_Received > DATE(2009,2,1) INTO CURSOR crsTest nofilter Local oExcel oExcel = Createobject("Excel.Application") With oExcel .DisplayAlerts = .F. .Workbooks.Add .Visible = .T. With .ActiveWorkBook *!* For ix = 1 To 3 && We want 3 Sheets *!* If .sheets.Count < m.ix *!* .sheets.Add(,.sheets(.sheets.Count)) && Add new sheets *!* Endif *!* ENDFOR * Name the sheets .WorkSheets(1).Name = "Employees" .WorkSheets(2).Name = "Customers" .WorkSheets(3).Name = "Order, OrderDetail, Products" && max sheetname is 31 chars * Start sending data * First one has headers specified VFP2Excel('crsTest', .WorkSheets(1).Range("A1") ) && To sheet1, start at A1 *!* VFP2Excel('crsCustomer', .WorkSheets(2).Range("A1") ) && To sheet2, start at A1 *!* VFP2Excel('crsOrders', .WorkSheets(3).Range("A1") ) && To sheet3, start at A1 *!* * Need to know where to put next *!* * Leave 2 columns empty - something like 'G1' *!* lcRange = _GetChar(.WorkSheets(3).UsedRange.Columns.Count + 3) + '1' *!* * To sheet3, start at next to previous *!* VFP2Excel('crsOrderDetail', .WorkSheets(3).Range(m.lcRange) ) *!* lcRange = _GetChar(.WorkSheets(3).UsedRange.Columns.Count + 3) + '1' *!* * To sheet3, start at next to previous *!* VFP2Excel('crsProducts', .WorkSheets(3).Range(m.lcRange) ) *!* #Define xlJustify -4130 *!* #Define xlTop -4160 *!* * I just happen to know notes in at column 5 from SQL *!* * No need to query from excel to keep code simple *!* * Lets format that column specially instead of leaving *!* * at the mercy of Excel's autofitting *!* .WorkSheets(1).UsedRange.VerticalAlignment = xlTop && set all to top *!* With .WorkSheets(1).Columns(5) *!* .ColumnWidth = 80 && 80 chars width *!* .WrapText = .T. *!* * .HorizontalAlignment = xlJustify && doesn't work good always *!* Endwith * Finally some cosmetic stuff For ix=1 To 3 With .WorkSheets(m.ix) .Columns.AutoFit .Rows.AutoFit Endwith Endfor .WorkSheets(1).Activate Endwith #Define xlWorkbookNormal -4143 * for another test save in current Excel version .ActiveWorkBook.SaveAs('c:\XLS_Files\ReadMeBack.xls',xlWorkbookNormal) Endwith * Warning: * Copying to a free table (might be dbc based) * temporarily and using field names as headers * if not passed. * This might lead to problems like: * Truncated fieldnames of 2 columns collide and copy to errors * Field names might be cryptic for the enduser Function VFP2Excel Lparameters tcCursorName, toRange, tcHeaders tcCursorName = Iif(Empty(m.tcCursorName),Alias(),m.tcCursorName) Local loConn As AdoDB.Connection, loRS As AdoDB.Recordset,; lcTemp, oExcel,ix lcTemp = Forcepath(Sys(2015)+'.dbf',Sys(2023)) Select (m.tcCursorName) Copy To (m.lcTemp) loConn = Createobject("Adodb.connection") loConn.ConnectionString = "Provider=VFPOLEDB;Data Source="+Sys(2023) loConn.Open() loRS = loConn.Execute("select * from " + m.lcTemp) * Use first row for headers Local Array aHeader[1] toRange.Offset(0,0).CopyFromRecordSet( loRS ) && Copy data starting from headerrow + 1 *!* For ix=1 To Iif( !Empty(m.tcHeaders), ; *!* ALINES(aHeader, m.tcHeaders,1,','), ; *!* loRS.Fields.Count ) *!* toRange.Offset(0,m.ix-1).Value = ; *!* Iif( !Empty(m.tcHeaders), ; *!* aHeader[m.ix], ; *!* Proper(loRS.Fields(m.ix-1).Name) ) *!* toRange.Offset(0,m.ix-1).Font.Bold = .T. *!* Endfor loRS.Close loConn.Close Erase (m.lcTemp) Endfunc * Return A, AA, BC etc notation for nth column Function _GetChar Lparameters tnColumn && Convert tnvalue to Excel alpha notation If m.tnColumn = 0 Return "" Endif If m.tnColumn <= 26 Return Chr(Asc("A")-1+m.tnColumn) Else Return _GetChar(Int(Iif(m.tnColumn % 26 = 0,m.tnColumn - 1, m.tnColumn) / 26)) + ; _GetChar((m.tnColumn-1)%26+1) Endif Endfunc>Naomi,