Some might like it, I'm sure some will be annoyed by it's lack of features too


I've left Paul Squires original comments in. A following post will be a ported example with comments on how to use this include file.
(No COM, DLLs, automation or installed copy of excel required)
(Don't try to create multple files at once, especially in different threads, it can't handle that) Let me know if you find any (more) bugs
Code: Select all
;Excel.wnc - Include file for BIFF 2.1 specifications to write Excel files.
;
;Converted from VB source to PowerBasic, November 2001.
;Paul Squires (2001) support@planetsquires.com (Freeware)
;
;Copyright (c) 2001 by Paul Squires.
;Although this code is available for free, the author retains the copyright, which means that you
;cannot do anything with it that is not expressly allowed by the author. In general terms, the author
;would allow the programmer to incorporate the code into their applications. Selling the code by
;itself is prohibited.
;
;
;Class file for writing Microsoft Excel BIFF 2.1 files.
;
;This class is intended for users who do not want to use the huge
;Jet or ADO providers if they only want to export their data to
;an Excel compatible file.
;Newer versions of Excel use the OLE Structure Storage methods
;which are quite complicated.
;Paul Squires, November 10, 2001
;support@planetsquires.com
;constants to hold cell alignment
#xlsGeneralAlign = 0
#xlsLeftAlign = 1
#xlsCentreAlign = 2
#xlsRightAlign = 3
#xlsFillCell = 4
#xlsLeftBorder = 8
#xlsRightBorder = 16
#xlsTopBorder = 32
#xlsBottomBorder = 64
#xlsShaded = 128
;constants to handle selecting the font for the cell
;used by rgbAttr2
;bits 0-5 handle the *picture* formatting, not bold/underline etc...
;bits 6-7 handle the font number
#xlsFont0 = 0
#xlsFont1 = 64
#xlsFont2 = 128
#xlsFont3 = 192
;used by rgbAttr1
;bits 0-5 must be zero
;bit 6 locked/unlocked
;bit 7 hidden/not hidden
#xlsCellNormal = 0
#xlsCellLocked = 64
#xlsCellHidden = 128
;set up variables to hold the spreadsheet;s layout
#xlsLeftMargin = 38
#xlsRightMargin = 39
#xlsTopMargin = 40
#xlsBottomMargin = 41
;add these enums together. For example: xlsBold + xlsUnderline
#xlsNoFormat = 0
#xlsBold = 1
#xlsItalic = 2
#xlsUnderline = 4
#xlsStrikeout = 8
Structure FONT_RECORD
opcode.w ;49
length.w ;5+len(fontname)
FontHeight.w
;bit0 bold, bit1 italic, bit2 underline, bit3 strikeout, bit4-7 reserved
FontAttributes1.b
FontAttributes2.b ;reserved - always 0
FontNameLength.b
EndStructure
Structure PASSWORD_RECORD
opcode.w ;47
length.w ;len(password)
EndStructure
Structure HEADER_FOOTER_RECORD
opcode.w ;20 Header, 21 Footer
length.w ;1+len(text)
TextLength.b
EndStructure
Structure PROTECT_SPREADSHEET_RECORD
opcode.w ;18
length.w ;2
Protect.w
EndStructure
Structure FORMAT_COUNT_RECORD
opcode.w ;1f
length.w ;2
Count.w
EndStructure
Structure FORMAT_RECORD
opcode.w ;1e
length.w ;1+len(format)
FormatLength.b ;len(format)
EndStructure ;+ followed by the Format-Picture
Structure COLWIDTH_RECORD
opcode.w ;36
length.w ;4
col1.b ;first column
col2.b ;last column
ColumnWidth.w ;at 1/256th of a character
EndStructure
;Beginning Of File record
Structure BEG_FILE_RECORD
opcode.w
length.w
version.w
ftype.w
EndStructure
;End Of File record
Structure END_FILE_RECORD
opcode.w
length.w
EndStructure
;true/false to print gridlines
Structure PRINT_GRIDLINES_RECORD
opcode.w
length.w
PrintFlag.w
EndStructure
;Integer record
Structure tInteger
opcode.w
length.w
Row.w ;unsigned integer
col.w
;rgbAttr1 handles whether cell is hidden and/or locked
rgbAttr1.b
;rgbAttr2 handles the Font# and Formatting assigned to this cell
rgbAttr2.b
;rgbAttr3 handles the Cell Alignment/borders/shading
rgbAttr3.b
intValue.w ;the actual integer value
EndStructure
;Number record
Structure tNumber
opcode.w
length.w
Row.w
col.w
rgbAttr1.b
rgbAttr2.b
rgbAttr3.b
NumberValue.D ;8 Bytes
EndStructure
;Label (Text) record
Structure tText
opcode.w
length.w
Row.w
col.w
rgbAttr1.b
rgbAttr2.b
rgbAttr3.b
TextLength.b
EndStructure
Structure MARGIN_RECORD_LAYOUT
opcode.w
length.w
MarginValue.D ;8 bytes
EndStructure
Structure HPAGE_BREAK_RECORD
opcode.w
length.w
NumPageBreaks.w
EndStructure
Structure DEF_ROWHEIGHT_RECORD
opcode.w
length.w
RowHeight.w
EndStructure
Structure ROW_HEIGHT_RECORD
opcode.w ;08
length.w ;should always be 16 bytes
RowNumber.w
FirstColumn.w
LastColumn.w
RowHeight.w ;written to file as 1/20ths of a point
internal.w
DefaultAttributes.b ;set to zero for no default attributes
FileOffset.w
rgbAttr1.b
rgbAttr2.b
rgbAttr3.b
EndStructure
Global xlsFileNumber.l
Global xlsBufferSize.l ;if > 0 buffer is active, also holds size of buffer.
;create an array that will hold the rows where a horizontal page
;break will be inserted just before.
Macro UBound(x):(PeekL((@x) - 8) - 1):EndMacro
Global Dim xlsHorizPageBreakRows.l(0)
Global xlsNumHorizPageBreaks.l
Declare.l xlsCreateFile(mFileName.s)
Declare.l xlsCloseFile()
Declare.l xlsInsertHorizPageBreak(lrow.l)
Declare.l xlsWriteInteger( value.w, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
Declare.l xlsWriteNumber( value.d, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
Declare.l xlsWriteText(value.s, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
Declare.l xlsWriteDate(DateString.s, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
Declare.l xlsSetMargin( Margin.l, MarginValue.w)
Declare.l xlsSetColumnWidth( FirstColumn.l, LastColumn.l, WidthValue.l)
Declare.l xlsSetFont(FontName.s, FontHeight.l, FontFormat.l)
Declare.l xlsSetHeader(HeaderText.s)
Declare.l xlsSetFooter(FooterText.s)
Declare.l xlsSetFilePassword(PasswordText.s)
Declare.l xlsPrintGridLines( TrueFalse.l)
Declare.l xlsProtectSpreadsheet( TrueFalse.l)
Declare.l xlsWriteDefaultFormats()
Declare.l xlsSetDefaultRowHeight( HeightValue.l)
Declare.l xlsSetRowHeight( lrow.l, HeightValue.l)
Declare.w ConvertRow( lrow.l)
Declare.w ConvertCol( lcol.l)
Declare.l DateToJulian(DateString.s)
Procedure.l xlsCreateFile(mFileName.s)
BEG_FILE_MARKER.BEG_FILE_RECORD
;beginning of file
BEG_FILE_MARKER\opcode = 9
BEG_FILE_MARKER\length = 4
BEG_FILE_MARKER\version = 2
BEG_FILE_MARKER\ftype = 10
xlsFileNumber = OpenFile(#PB_Any, mFileName)
WriteData(xlsFileNumber,@BEG_FILE_MARKER, SizeOf(BEG_FILE_MARKER))
xlsWriteDefaultFormats()
;create the Horizontal Page Break array
ReDim xlsHorizPageBreakRows(0)
xlsNumHorizPageBreaks = 0
ProcedureReturn 0 ;return with no error
EndProcedure
Procedure.l xlsCloseFile()
If xlsFileNumber = 0
ProcedureReturn -1
;EXIT FUNCTION
EndIf
;write the horizontal page breaks if necessary
If xlsNumHorizPageBreaks > 0
SortArray(xlsHorizPageBreakRows(), #PB_Sort_Ascending)
;write the Horizontal Page Break Record
HORIZ_PAGE_BREAK.HPAGE_BREAK_RECORD
HORIZ_PAGE_BREAK\opcode = 27
HORIZ_PAGE_BREAK\length = 2 + (xlsNumHorizPageBreaks * 2)
HORIZ_PAGE_BREAK\NumPageBreaks = xlsNumHorizPageBreaks
WriteData(xlsFileNumber,@HORIZ_PAGE_BREAK, SizeOf(HORIZ_PAGE_BREAK))
;now write the actual page break values
For x.l = 1 To xlsNumHorizPageBreaks
st.w = (xlsHorizPageBreakRows(x))
WriteData(xlsFileNumber,@st, SizeOf(st))
Next
EndIf
END_FILE_MARKER.END_FILE_RECORD
;end of file marker
END_FILE_MARKER\opcode = 10
WriteData(xlsFileNumber,@END_FILE_MARKER, SizeOf(END_FILE_MARKER))
CloseFile(xlsFileNumber)
ProcedureReturn 0 ;return with no error code
EndProcedure
Procedure.l xlsInsertHorizPageBreak( lrow.l)
;the row and column values are written to the excel file as
;unsigned integers. Therefore, must convert the longs to integer.
If lrow > 32767
Row.w = (lrow - 65536) ;cint()
Else
Row.w = (lrow) - 1 ;rows/cols in Excel binary file are zero based
EndIf
xlsNumHorizPageBreaks = xlsNumHorizPageBreaks + 1
ReDim xlsHorizPageBreakRows(xlsNumHorizPageBreaks)
xlsHorizPageBreakRows(xlsNumHorizPageBreaks) = Row
ProcedureReturn 0
EndProcedure
Procedure.w ConvertRow( lrow.l)
;the row and column values are written to the excel file as
;integers. Therefore, must convert the longs to integer.
If lrow > 32767
ProcedureReturn (lrow - 65536) ;CINT
Else
ProcedureReturn (lrow) - 1 ;rows/cols in Excel binary file are zero based
EndIf
EndProcedure
Procedure.w ConvertCol( lcol.l)
;the row and column values are written to the excel file as
;integers. Therefore, must convert the longs to integer.
If lcol > 32767
ProcedureReturn (lcol - 65536) ;CINT
Else
ProcedureReturn (lcol) - 1 ;rows/cols in Excel binary file are zero based
EndIf
EndProcedure
Procedure.l xlsWriteInteger( value.w, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
;convert the row, col from LONG to INTEGER.
Row.w = ConvertRow(lrow.l)
Col.w = ConvertCol(lcol.l)
INTEGER_RECORD.tInteger
INTEGER_RECORD\opcode = 2
INTEGER_RECORD\length = 9
INTEGER_RECORD\Row = Row
INTEGER_RECORD\col = col
INTEGER_RECORD\rgbAttr1 = (HiddenLocked.l) ;CBYT
INTEGER_RECORD\rgbAttr2 = (CellFont.l + CellFormat.l)
INTEGER_RECORD\rgbAttr3 = (CellAlignment.l)
INTEGER_RECORD\intValue = value
WriteData(xlsFileNumber,@INTEGER_RECORD, SizeOf(INTEGER_RECORD))
ProcedureReturn 0 ;return with no error
EndProcedure
Procedure.l xlsWriteNumber( value.d, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
;convert the row, col from LONG to INTEGER.
Row.w = ConvertRow(lrow.l)
Col.w = ConvertCol(lcol.l)
NUMBER_RECORD.tNumber
NUMBER_RECORD\opcode = 3
NUMBER_RECORD\length = 15
NUMBER_RECORD\Row = Row
NUMBER_RECORD\col = col
NUMBER_RECORD\rgbAttr1 = (HiddenLocked) ;CBYT
NUMBER_RECORD\rgbAttr2 = (CellFont.l + CellFormat)
NUMBER_RECORD\rgbAttr3 = (CellAlignment)
NUMBER_RECORD\NumberValue = value
WriteData(xlsFileNumber,@NUMBER_RECORD, SizeOf(NUMBER_RECORD))
ProcedureReturn 0 ;return with no error
EndProcedure
Procedure.l xlsWriteText(value.s, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
;convert the row, col from LONG to INTEGER.
Row.w = ConvertRow(lrow.l)
Col.w = ConvertCol(lcol.l)
Protected b.b
st.s = value
l.l = Len(st)
Protected TEXT_RECORD.tText
TEXT_RECORD\opcode = 4
TEXT_RECORD\length = 10
;Length of the text portion of the record
TEXT_RECORD\TextLength = l.l
;Total length of the record
TEXT_RECORD\length = 8 + l.l
TEXT_RECORD\Row = Row
TEXT_RECORD\col = col
TEXT_RECORD\rgbAttr1 = (HiddenLocked.l) ;CBYT
TEXT_RECORD\rgbAttr2 = (CellFont.l + CellFormat.l)
TEXT_RECORD\rgbAttr3 = (CellAlignment.l)
WriteData(xlsFileNumber,@TEXT_RECORD, SizeOf(TEXT_RECORD))
;Then the actual string data
For a.l = 1 To l.l
b = Asc(Mid(st, a, 1))
WriteData(xlsFileNumber,@b, 1)
Next
ProcedureReturn 0 ;return with no error
EndProcedure
Procedure.l xlsWriteDate(DateString.s, lrow.l, lcol.l, CellFont.l, CellAlignment.l, HiddenLocked.l, CellFormat.l)
;convert the row, col from LONG to INTEGER.
Row.w = ConvertRow(lrow.l)
Col.w = ConvertCol(lcol.l)
;convert the DateString$ from YYYYMMDD to a Julian date number
value.l= (DateToJulian.l(DateString) - DateToJulian.l("19000100")) + 1
NUMBER_RECORD.tNumber
NUMBER_RECORD\opcode = 3
NUMBER_RECORD\length = 15
NUMBER_RECORD\Row = Row
NUMBER_RECORD\col = col
NUMBER_RECORD\rgbAttr1 = (HiddenLocked.l) ;CBYT
NUMBER_RECORD\rgbAttr2 = (CellFont.l + CellFormat.l)
NUMBER_RECORD\rgbAttr3 = (CellAlignment.l)
NUMBER_RECORD\NumberValue = (value.l) ;CDBL
WriteData(xlsFileNumber,@NUMBER_RECORD, SizeOf(NUMBER_RECORD))
ProcedureReturn 0 ;return with no error
EndProcedure
Procedure.l xlsSetMargin( Margin.l, MarginValue.w)
;write the spreadsheet;s layout information (in inches)
MARGINRECORD.MARGIN_RECORD_LAYOUT
;Margin.l should be one of the following....
;#xlsLeftMargin = 38
;#xlsRightMargin = 39
;#xlsTopMargin = 40
;#xlsBottomMargin = 41
MARGINRECORD\opcode = Margin.l
MARGINRECORD\length = 8
MARGINRECORD\MarginValue = MarginValue ;in inches
WriteData(xlsFileNumber,@MARGINRECORD, SizeOf(MARGINRECORD))
ProcedureReturn 0
EndProcedure
Procedure.l xlsSetColumnWidth( FirstColumn.l, LastColumn.l, WidthValue.l)
COLWIDTH.COLWIDTH_RECORD
COLWIDTH\opcode = 36
COLWIDTH\length = 4
COLWIDTH\col1 = (FirstColumn.l) - 1 ;CBYT
COLWIDTH\col2 = (LastColumn.l) - 1
COLWIDTH\ColumnWidth = WidthValue.l * 256 ;values are specified as 1/256 of a character
WriteData(xlsFileNumber,@COLWIDTH, SizeOf(COLWIDTH))
ProcedureReturn 0
EndProcedure
Procedure.l xlsSetFont(FontName.s, FontHeight.l, FontFormat.l)
;you can set up to 4 fonts in the spreadsheet file. When writing a value such
;as a Text or Number you can specify one of the 4 fonts (numbered 0 to 3)
FONTNAME_RECORD.FONT_RECORD
l.l = Len(FontName)
FONTNAME_RECORD\opcode = 49
FONTNAME_RECORD\length = 5 + l.l
FONTNAME_RECORD\FontHeight = FontHeight.l * 20
FONTNAME_RECORD\FontAttributes1 = (FontFormat.l) ;bold/underline etc... CBYT
FONTNAME_RECORD\FontAttributes2 = (0) ;reserved-always zero!!
FONTNAME_RECORD\FontNameLength = (l.l)
WriteData(xlsFileNumber,@FONTNAME_RECORD, SizeOf(FONTNAME_RECORD))
;Then the actual font name data
Protected b.b
For a.l = 1 To l.l
b.b = Asc(Mid(FontName, a.l, 1))
WriteData(xlsFileNumber,@b, 1)
Next
ProcedureReturn 0
EndProcedure
Procedure.l xlsSetHeader(HeaderText.s)
HEADER_RECORD.HEADER_FOOTER_RECORD
l.l = Len(HeaderText)
HEADER_RECORD\opcode = 20
HEADER_RECORD\length = 1 + l.l
HEADER_RECORD\TextLength = (l.l) ;CBYT
WriteData(xlsFileNumber,@HEADER_RECORD, SizeOf(HEADER_RECORD))
;Then the actual Header text
Protected b.b
For a.l = 1 To l.l
b.b = Asc(Mid(HeaderText, a.l, 1))
WriteData(xlsFileNumber,@b, 1)
Next
ProcedureReturn 0
EndProcedure
Procedure.l xlsSetFooter(FooterText.s)
FOOTER_RECORD.HEADER_FOOTER_RECORD
l.l = Len(FooterText)
FOOTER_RECORD\opcode = 21
FOOTER_RECORD\length = 1 + l.l
FOOTER_RECORD\TextLength = (l.l) ;CBYT
WriteData(xlsFileNumber,@FOOTER_RECORD, SizeOf(FOOTER_RECORD))
;Then the actual Header text
Protected b.b
For a.l = 1 To l.l
b.b = Asc(Mid(FooterText, a.l, 1))
WriteData(xlsFileNumber,@b, 1)
Next
ProcedureReturn 0
EndProcedure
Procedure.l xlsSetFilePassword(PasswordText.s)
FILE_PASSWORD_RECORD.PASSWORD_RECORD
l.l = Len(PasswordText)
FILE_PASSWORD_RECORD\opcode = 47
FILE_PASSWORD_RECORD\length = l
WriteData(xlsFileNumber,@FILE_PASSWORD_RECORD, SizeOf(FILE_PASSWORD_RECORD))
;Then the actual Password text
Protected b.b
For a.l = 1 To l.l
b.b = Asc(Mid(PasswordText, a.l, 1))
WriteData(xlsFileNumber,@b, 1)
Next
ProcedureReturn 0
EndProcedure
Procedure.l xlsPrintGridLines( TrueFalse.l)
GRIDLINES_RECORD.PRINT_GRIDLINES_RECORD
GRIDLINES_RECORD\opcode = 43
GRIDLINES_RECORD\length = 2
If TrueFalse.l = 0
GRIDLINES_RECORD\PrintFlag = 0
Else
GRIDLINES_RECORD\PrintFlag = 1
EndIf
WriteData(xlsFileNumber,@GRIDLINES_RECORD, SizeOf(GRIDLINES_RECORD))
ProcedureReturn 0
EndProcedure
Procedure.l xlsProtectSpreadsheet( TrueFalse.l)
PROTECT_RECORD.PROTECT_SPREADSHEET_RECORD
PROTECT_RECORD\opcode = 18
PROTECT_RECORD\length = 2
If TrueFalse.l = 0
PROTECT_RECORD\Protect = 0
Else
PROTECT_RECORD\Protect = 1
EndIf
WriteData(xlsFileNumber,@PROTECT_RECORD, SizeOf(PROTECT_RECORD))
ProcedureReturn 0
EndProcedure
Procedure.l xlsWriteDefaultFormats()
cFORMAT_COUNT_RECORD.FORMAT_COUNT_RECORD
cFORMAT_RECORD.FORMAT_RECORD
Protected lIndex.l
Dim aFormat.s(23) ;As STRING
aFormatCount = 23
Protected l.l
Protected q.s
q = Chr(34)
aFormat(0) = "General"
aFormat(1) = "0"
aFormat(2) = "0.00"
aFormat(3) = "#,##0"
aFormat(4) = "#,##0.00"
aFormat(5) = "#,##0\ " + q + "$" + q + ";\-#,##0\ " + q + "$" + q
aFormat(6) = "#,##0\ " + q + "$" + q + ";[Red]\-#,##0\ " + q + "$" + q
aFormat(7) = "#,##0.00\ " + q + "$" + q + ";\-#,##0.00\ " + q + "$" + q
aFormat(8) = "#,##0.00\ " + q + "$" + q + ";[Red]\-#,##0.00\ " + q + "$" + q
aFormat(9) = "0%"
aFormat(10) = "0.00%"
aFormat(11) = "0.00E+00"
aFormat(12) = "yyyy-mm-dd"
aFormat(13) = "dd/\ mmm\ yy"
aFormat(14) = "dd/\ mmm"
aFormat(15) = "mmm\ yy"
aFormat(16) = "h:mm\ AM/PM"
aFormat(17) = "h:mm:ss\ AM/PM"
aFormat(18) = "hh:mm"
aFormat(19) = "hh:mm:ss"
aFormat(20) = "dd/mm/yy\ hh:mm"
aFormat(21) = "##0.0E+0"
aFormat(22) = "mm:ss"
aFormat(23) = "@"
cFORMAT_COUNT_RECORD\opcode = $1F
cFORMAT_COUNT_RECORD\length = $2
cFORMAT_COUNT_RECORD\Count = aFormatCount ;(UBOUND(aFormat)) ;CBYT
WriteData(xlsFileNumber,@cFORMAT_COUNT_RECORD, SizeOf(cFORMAT_COUNT_RECORD))
For lIndex = 0 To aFormatCount ;LBOUND(aFormat)
l = Len(aFormat(lIndex))
cFORMAT_RECORD\opcode = $1E
cFORMAT_RECORD\length = l + 1
cFORMAT_RECORD\FormatLength = l
WriteData(xlsFileNumber,@cFORMAT_RECORD, SizeOf(cFORMAT_RECORD))
;Then the actual format
Protected b.b, a.l
For a = 1 To l
b.b = Asc(Mid(aFormat(lIndex), a, 1))
WriteData(xlsFileNumber,@b, 1)
Next
Next
ProcedureReturn 0
EndProcedure
Procedure.l xlsSetDefaultRowHeight( HeightValue.l)
;Height is defined in units of 1/20th of a point. Therefore, a 10-point font
;would be 200 (i.e. 200/20 = 10). This Procedure takes a HeightValue such as
;14 point and converts it the correct size before writing it to the file.
DEFHEIGHT.DEF_ROWHEIGHT_RECORD
DEFHEIGHT\opcode = 37
DEFHEIGHT\length = 2
DEFHEIGHT\RowHeight = HeightValue.l * 20 ;convert points to 1/20ths of point
WriteData(xlsFileNumber,@DEFHEIGHT, SizeOf(DEFHEIGHT))
ProcedureReturn 0
EndProcedure
Procedure.l xlsSetRowHeight( lrow.l, HeightValue.l)
;convert the row, col from LONG to INTEGER.
Row.w = ConvertRow(lrow.l)
;Height is defined in units of 1/20th of a point. Therefore, a 10-point font
;would be 200 (i.e. 200/20 = 10). This Procedure takes a HeightValue such as
;14 point and converts it the correct size before writing it to the file.
ROWHEIGHTREC.ROW_HEIGHT_RECORD
ROWHEIGHTREC\opcode = 8
ROWHEIGHTREC\length = 16
ROWHEIGHTREC\RowNumber = Row
ROWHEIGHTREC\FirstColumn = 0
ROWHEIGHTREC\LastColumn = 256
ROWHEIGHTREC\RowHeight = HeightValue.l * 20 ;convert points to 1/20ths of point
ROWHEIGHTREC\internal = 0
ROWHEIGHTREC\DefaultAttributes = 0
ROWHEIGHTREC\FileOffset = 0
ROWHEIGHTREC\rgbAttr1 = 0
ROWHEIGHTREC\rgbAttr2 = 0
ROWHEIGHTREC\rgbAttr3 = 0
WriteData(xlsFileNumber,@ROWHEIGHTREC, SizeOf(ROWHEIGHTREC))
ProcedureReturn 0
EndProcedure
Procedure.l DateToJulian(DateString.s)
;DateString$ must be in YYYYMMDD
Protected Elapsed.l
If Len(DateString) <> 8
ProcedureReturn 0
;EXIT FUNCTION
EndIf
Year.l = Val(Left(DateString, 4))
month.l = Val(Mid(DateString, 5, 2))
day.l = Val(Right(DateString, 2))
If month.l < 3 ; January or February?
month.l = month.l + 12 ; 13th or 14th month ....
year = year - 1 ; .... of prev. year
EndIf
Elapsed = Int((year.l + 4712) * 365.25) ; years elapsed
Elapsed = Elapsed - (year.l / 100) ; substract century leapdays
Elapsed = Elapsed + (year.l / 400) ; re-add valid ones
Elapsed = Elapsed + (30.6 * (month - 1) + 0.2) ; months elapsed + adjustm. ;INT()
ProcedureReturn Elapsed + day.l ; days of final month
EndProcedure