I already thought that I more or less figured out the conversion dbf in Excel. But here again there was an old problem, seemingly out of the blue. dbf-file the most common. I want to just write dbf-file in Excel with the given names of speakers and an error of execution.

I am your function slightly modified so that it did not pass the line at the start of Excel-file. Yet there is something slightly different because an error occurred. Here is the text that I use:
Code: Select all
*******************
******** DBF => XLS
*******************
* -------------
FUNCTION DC_WorkArea2Excel( cExcelFile, nOrientation, lDisplayAlerts, ;
lVisible, aFields, lAutoFit, cDateFormat, aFieldEvals, ;
cPassword, lFreezeRow1, lCsvFallBack, aColumnNames )
LOCAL oExcel, oBook, oSheet, nRow, aStru, i, cHeader, ;
cFieldName, cFieldType, nFieldLen, nFieldDec, cFormat, ;
xValue, GetList[0], GetOptions, oDlg, nCount := 0, ;
cDbfName, nKeyCount, oProgress, lStatus := .t., aData, ;
cRow, cColumns, cRange, aRow, bError, aStru2, nFound, ;
cFieldValue, nFieldBlock
DEFAULT nOrientation := xlLandscape, ;
lDisplayAlerts := .f., ;
lVisible := .f., ;
lAutoFit := .f., ;
cDateFormat := "US", ; // US, USSHORT, EURO, EUROSHORT, or send custom?
aFieldEvals := {}, ;
cExcelFile := DC_Path(AppName(.t.)) + 'worksheet.xls', ;
lFreezeRow1 := .t., ;
lCsvFallBack := .f.
// aFieldEvals -> {{FIELDNAME,CodeBlock},....} Code blocks to evaluate for specific fields
#if XPPVER > 1900000
// Create the "Excel.Application" object
IF '.CSV' $ Upper(cExcelFile)
RETURN DC_WorkArea2Csv(cExcelFile)
ENDIF
oExcel := CreateObject("Excel.Application")
IF Empty( oExcel )
IF lCsvFallBack
DCMSGBOX 'Excel is not installed. Create CSV file instead?' YESNO TO lStatus
IF lStatus
RETURN DC_WorkArea2Csv(cExcelFile)
ELSE
RETURN .f.
ENDIF
ELSE
DC_WinAlert( "Excel is not installed" )
ENDIF
RETURN .f.
ENDIF
#else
DC_WinAlert('This feature is available in Xbase++ 1.9 and later only!')
RETURN .f.
#endif
IF upper(cDateFormat) = "USSHORT"
cDateFormat := "m\/d\/yyyy;@"
ELSEIF upper(cDateFormat) = "US"
cDateFormat := "mm\/dd\/yyyy;@"
ELSEIF upper(cDateFormat) = "EUROSHORT"
cDateFormat := "d\/m\/yyyy;@"
ELSEIF upper(cDateFormat) = "EURO"
cDateFormat := "dd\/mm\/yyyy;@"
ENDIF
// Avoid message boxes such as "File already exists". Also,
// ensure the Excel application is visible.
oExcel:DisplayAlerts := lDisplayAlerts
oExcel:visible := lVisible
// Add a workbook to the Excel application. Query for
// the active sheet (sheet-1) and set up page/paper
// orientation.
cDbfName := dbInfo(DBO_FILENAME)
IF cDbfName = '<CURSOR>'
nKeyCount := RecCount()
ELSE
nKeyCount := DC_KeyCount()
ENDIF
@ 0,0 DCSAY 'Creating Excel Worksheet: ' + cExcelFile SAYSIZE 0
@ 1,0 DCPROGRESS oProgress SIZE 50,1 ;
TYPE XBPSTATIC_TYPE_TEXT ;
COLOR GRA_CLR_CYAN, GRA_CLR_WHITE ;
PERCENT ;
PERCENTCOLOR GRA_CLR_RED ;
RADIUS 20 ;
OUTLINE ;
DYNAMIC ;
EVERY Int(nKeyCount/100)
@ 3,0 DCPUSHBUTTON CAPTION 'Cancel' SIZE 9,1.2 ACTION {||lStatus:=.f.}
DCGETOPTIONS NORESIZE ALWAYSONTOP _PIXEL .f.
DCREAD GUI FIT TITLE 'Exporting to Excel' ;
MODAL EXIT PARENT @oDlg OPTIONS GetOptions NOAUTORESTORE
oBook := oExcel:workbooks:Add()
oSheet := oBook:ActiveSheet
oSheet:PageSetup:Orientation := nOrientation
DC_DbGoTop()
nRow := 1
// Feed in the data from the table to the Cells
// of the sheet.
aStru := dbStruct()
IF Valtype(aFields) == 'A'
aStru2 := AClone(aStru)
aStru := Array(0)
FOR i := 1 TO Len(aFields)
cFieldName := Upper(Alltrim(aFields[i]))
nFound := AScan(aStru2,{|a|Upper(a[1])==cFieldName})
IF nFound > 0
AAdd( aStru, aStru2[nFound] )
ENDIF
NEXT
ENDIF
aFields := Array(0)
FOR i := 1 TO Len(aStru)
cFieldName := aStru[i,1]
nFieldDec := aStru[i,4]
IF Valtype(&(cFieldName)) $ 'NF'
IF nFieldDec == 0
cFormat := '0'
ELSE
cFormat := '0.' + Repl('0',nFieldDec)
ENDIF
ELSEIF Valtype(&(cFieldName))=='D'
cFormat := cDateFormat
ELSEIF Valtype(&(cFieldName)) $ 'CM'
cFormat := "@" // Preserves leading 0s on strings that look like numbers
ELSE
cFormat := ''
ENDIF
AAdd(aFields,{cFieldName,cFieldName,cFormat})
NEXT
FOR i := 1 TO Len(aFields)
IF Len(aFields[i]) < 3
ASize(aFields[i],3)
ENDIF
IF Valtype(aColumnNames) == 'A' .AND. Len(aColumnNames) == Len(aFields)
cHeader := aColumnNames[i]
ELSE
cHeader := aFields[i,2] // Чтобы не писала имена полей
ENDIF
IF !Empty(cHeader)
oSheet:Cells(nRow,i):Value := cHeader
ENDIF
cFormat := aFields[i,3]
IF !Empty(cFormat)
* MsgBox(cFormat) // Отладка. Функция преобразования xls=>dbf формирует файл со странным форматом числовых полей
cFormat := '0.' + Repl('0',nFieldDec)
oSheet:Columns(i):NumberFormat := cFormat // <<<===== IN THIS LINE, AN ERROR OCCURS
ENDIF
NEXT
aRow := Array(Len(aStru))
aData := Array(0)
cColumns := Get_Excel_Column_ID(Len(aRow))
nRow += 2
DO WHILE !DC_Eof() .AND. lStatus
DC_CompleteEvents()
DC_GetProgress(oProgress,nCount++,nKeyCount)
FOR i := 1 TO Len(aFields)
cFieldName := aFields[i,1]
cFieldValue := &(cFieldName)
nFieldBlock := aScan(aFieldEvals,{|a|upper(a[1])==upper(cFieldName)})
IF nFieldBlock > 0
cFieldValue := Eval(aFieldEvals[nFieldBlock,2],cFieldValue)
ENDIF
IF Valtype(cFieldValue) == 'D'
aRow[i] := Dtoc(cFieldValue)
ELSEIF Valtype(cFieldValue) $ 'CM'
aRow[i] := Trim(cFieldValue)
ELSE
aRow[i] := cFieldValue
ENDIF
NEXT
AAdd( aData, AClone(aRow) )
nRow++
DC_DbSkip(1)
ENDDO
*cRange := 'A3:' + cColumns + Ltrim(Str(nRow-1))
cRange := 'A2:' + cColumns + Ltrim(Str(nRow-2)) // Чтобы не было пустой строки
oDlg:destroy()
oSheet:Range(cRange):Value := aData
// Force a reformat for the size of the first column
IF lAutoFit
FOR i := 1 TO Len(aFields)
oSheet:Columns(i):AutoFit()
NEXT
ENDIF
IF lFreezeRow1
oSheet:Range("A1:A1"):EntireRow:Font:Bold := .t.
oSheet:Activate()
oSheet:Application:ActiveWindow:SplitRow := 1
oSheet:Application:ActiveWindow:FreezePanes := .T.
ENDIF
bError := ErrorBlock( {|e| Break(e) } )
BEGIN SEQUENCE
// Save workbook as ordinary excel file.
oBook:SaveAs(cExcelFile,xlWorkbookNormal,cPassword)
RECOVER
END SEQUENCE
ErrorBlock(bError)
oSheet:destroy()
oBook:close()
oBook:destroy()
// Quit Excel
oExcel:Quit()
oExcel:Destroy()
RETURN .t.
* ------------
[/size]
Here, the database:
http://lc.kubagro.ru/Dima/Klas_res.dbf
The Program:
Code: Select all
aColumnNames := {}
AADD(aColumnNames, 'Код класса')
AADD(aColumnNames, 'Наименование класса')
AADD(aColumnNames, 'Начальный ресурс класса')
AADD(aColumnNames, 'Остаток ресурса класса')
AADD(aColumnNames, 'Количество объектов, назначенных на класс')
AADD(aColumnNames, 'Суммарное сходство назначенных объектов')
AADD(aColumnNames, 'Суммарные затраты на назначенные объекты')
AADD(aColumnNames, 'Средневзвешенное удельное сходство')
AADD(aColumnNames, 'Средний на объект уровень сходства')
AADD(aColumnNames, 'Средние на объект затраты')
*DC_WorkArea2Excel( cExcelFile, nOrientation, lDisplayAlerts, ;
* lVisible, aFields, lAutoFit, cDateFormat, aFieldEvals, ;
* cPassword, aColumnNames )
cExcelFile = M_ApplsPath+"\Inp_data\Klas_res.xls"
CLOSE ALL
USE Klas_res EXCLUSIVE NEW;N_Cls = RECCOUNT()
SELECT Klas_res
DC_DbGoTop()
DC_WorkArea2Excel( cExcelFile ,,,,,,,,,,, aColumnNames )
[/size]