Xbasic

Office Example: Multiple spreadsheets

Description

This example creates a multiple spreadsheets in a single document:

  1. Summarized Daily Sales and Expenses - contains totals for a single week.

  2. Summarized Product Sales

The spreadsheet is populated with a title, column headings, labels, and formulas to calculate the daily gross profit, summarize the weeks sales and expenses and the week's gross profit.

After the spreadsheets are created, the workbook is opened in Microsoft Excel.

dim Doc as Office::ExcelDocument ' Declare the document variable
dim DocumentFile as C = "C:\temp\A5OfficeSample2.xlsx"

' Compute the date of the most recent Sunday
dim StartDate as D = date() - (dow(date()) - 1)

CreateDailySalesAndExpenses(Doc, StartDate)
CreateProductSalesSummary(Doc, StartDate)

Path = file.filename_parse(DocumentFile, "P")
on error resume next
File.Dir_Create(Path)
on error goto 0
if Doc.Save(DocumentFile)
    ' Release all references to the document because we are about to open it in Excel
    delete Doc
    sys_open(DocumentFile)
else    
    ui_msg_box("Error Saving Document", "Unable to save document to " + DocumentFile + ":" + crlf(2) + Doc.ErrorMessage)
end if    




FUNCTION CreateDailySalesAndExpenses as V(Doc as Office::ExcelDocument, StartDate as D)
    
dim Sheet as Office::Spreadsheet ' Pointer to the spreadsheet

' Layout of the spreadsheet
dim TitleRow   as N = 1
dim HeadingRow as N = 4
dim DetailRow  as N = 6

' Create a new spreadsheet
Sheet = Doc.AddSheet("Weekly Sales and Expenses") ' Create a new spreadsheet

WritePageHeadings(Doc, Sheet, TitleRow, 5, "Weekly Sales & Expenses Summary" + crlf() + "Week Beginning " + StartDate)
WriteColumnHeadings(Doc, Sheet, HeadingRow, <<%txt%
Day|C|10
Date|D
Daily Sales|$
Daily Expenses|$
Gross Daily Profit|$
%txt%)
Daily_WriteData(StartDate, Doc, Sheet, DetailRow)
END FUNCTION


FUNCTION Daily_WriteData as L (StartDate as D, Doc as Office::ExcelDocument, Sheet as Office::Spreadsheet, StartRow as N)
' Write the detail data and a total line
dim NumericFormat   as Office::Format ' Pointer to the format for numeric columns
dim DateFormat      as Office::Format ' Pointer to the format for the date column
dim CharacterFormat as Office::Format ' Pointer to the format for labels
dim Font            as Office::Font   ' Pointer to the font for column data
dim LabelFont       as Office::Font   ' Pointer to the font for labels 
dim Sales           as N
dim Expenses        as N
dim ProfitFormula   as C

' Create a font for the detail data
Font = Doc.AddFont()
Font.Color = Office::Color::Black
Font.Name = "Tahoma"
Font.Size = 10
Font.Bold = .f.

' Create a format for numeric columns
NumericFormat = Doc.AddFormat()
NumericFormat.Font = Font    ' Set the font into the column heading format
NumericFormat.HorizontalAlignment = Office::HorizontalAlignment::Right
NumericFormat.NumericFormat = Office::NumericFormat::CurrencyDec2NegBracketedInRed

' Create a format for the date column
DateFormat = Doc.AddFormat()
DateFormat.Font = Font    ' Set the font into the column heading format
DateFormat.HorizontalAlignment = Office::HorizontalAlignment::Right
DateFormat.NumericFormat = Office::NumericFormat::Date

' Create a format for the character column
LabelFont = Doc.AddFont()
LabelFont.Color = Office::Color::DarkBlue
LabelFont.Name = "Tahoma"
LabelFont.Size = 10
LabelFont.Bold = .t.
LabelFormat = Doc.AddFormat()
LabelFormat.Font = LabelFont    ' Set the font into the column heading format
LabelFormat.HorizontalAlignment = Office::HorizontalAlignment::Left

' Loop through the days of the week to create the detail
for i = 1 to 7
    CurrentDate = StartDate + (i - 1)                 ' Get the date of the current day of the week
    Row         = StartRow + i - 1                    ' Compute the spreadsheet row
    GetSalesAndExpenses(CurrentDate, Sales, Expenses) ' Call a test function that generates random data
    ProfitFormula = "C" + Row + " - D" + Row          ' Create a formula for profit = sales - expenses
    
    Sheet.Write(Row, 1, CDow(CurrentDate), LabelFormat) ' Day of the week
    Sheet.Write(Row, 2, CurrentDate, DateFormat)        ' Date
    Sheet.Write(Row, 3, Sales, NumericFormat)           ' Sales
    Sheet.Write(Row, 4, Expenses, NumericFormat)        ' Expenses
    Sheet.WriteFormula(Row, 5, ProfitFormula, NumericFormat) ' Profit
next

' Write the total line
Row = StartRow + 9
ProfitFormula = "C" + Row + " - D" + Row
Sheet.Write(Row, 1, "Total", LabelFormat)
Sheet.WriteFormula(Row, 3, "SUM(C" + StartRow + ":C" + (StartRow + 6) + ")", NumericFormat) ' Sum of Sales
Sheet.WriteFormula(Row, 4, "SUM(D" + StartRow + ":D" + (StartRow + 6) + ")", NumericFormat) ' Sum of Expenses
Sheet.WriteFormula(Row, 5, ProfitFormula, NumericFormat) ' Profit

Sample1_WriteData = .t.
END FUNCTION




FUNCTION CreateProductSalesSummary as V(Doc as Office::ExcelDocument, StartDate as D)
dim Sheet as Office::Spreadsheet ' Pointer to the spreadsheet

' Layout of the spreadsheet
dim TitleRow   as N = 1
dim HeadingRow as N = 4
dim DetailRow  as N = 6

' Create a new spreadsheet
Sheet = Doc.AddSheet("Weekly Product Sales") ' Create a new spreadsheet

WritePageHeadings(Doc, Sheet, TitleRow, 3, "Product Sales" + crlf() + "Week Beginning " + StartDate)
WriteColumnHeadings(Doc, Sheet, HeadingRow, <<%txt%
Product|C|12
Weekly Sales|$
Average Daily Sales|$
%txt%)
Product_WriteData(StartDate, Doc, Sheet, DetailRow)
END FUNCTION                


FUNCTION Product_WriteData as L (StartDate as D, Doc as Office::ExcelDocument, Sheet as Office::Spreadsheet, StartRow as N)
' Write the detail data and a total line
dim NumericFormat as Office::Format ' Pointer to the format for numeric columns
dim DateFormat    as Office::Format ' Pointer to the format for the date column
dim LabelFormat   as Office::Format ' Pointer to the format for labels
dim Font          as Office::Font   ' Pointer to the font for column data
dim LabelFont     as Office::Font   ' Pointer to the font for labels 
dim Sales         as N
dim ProductText   as C = GetProductList()
dim Products      as N = w_count(ProductText)
dim TotalRow      as N = StartRow + Products + 1

' Create a font for the detail data
Font = Doc.AddFont()
Font.Color = Office::Color::Black
Font.Name = "Tahoma"
Font.Size = 10
Font.Bold = .f.

' Create a format for numeric columns
NumericFormat = Doc.AddFormat()
NumericFormat.Font = Font    ' Set the font into the column heading format
NumericFormat.HorizontalAlignment = Office::HorizontalAlignment::Right
NumericFormat.NumericFormat = Office::NumericFormat::CurrencyDec2NegBracketedInRed

' Create a format for the date column
DateFormat = Doc.AddFormat()
DateFormat.Font = Font    ' Set the font into the column heading format
DateFormat.HorizontalAlignment = Office::HorizontalAlignment::Right
DateFormat.NumericFormat = Office::NumericFormat::Date

' Create a format for the character column
LabelFont = Doc.AddFont()
LabelFont.Color = Office::Color::DarkBlue
LabelFont.Name = "Tahoma"
LabelFont.Size = 10
LabelFont.Bold = .t.
LabelFormat = Doc.AddFormat()
LabelFormat.Font = LabelFont    ' Set the font into the column heading format
LabelFormat.HorizontalAlignment = Office::HorizontalAlignment::Left

' Loop through the days of the week to create the detail
for i = 1 to Products
    ProductName = AllTrim(Word(ProductText, i, crlf()))
    Row         = StartRow + i - 1                       ' Compute the spreadsheet row
    GetProductWeeklySales(ProductName, StartDate, Sales) ' Call a test function that generates random data
    
    Sheet.Write(Row, 1, ProductName, LabelFormat) ' Product
    Sheet.Write(Row, 2, Sales, NumericFormat)     ' Sales
    AverageFormula = "B" + Row + " / 7"
    Sheet.WriteFormula(Row, 3, AverageFormula, NumericFormat) ' Average Daily Sales
next

' Write the total line
Sheet.Write(TotalRow, 1, "Total", LabelFormat)
Sheet.WriteFormula(TotalRow, 2, "SUM(B" + StartRow + ":B" + (StartRow + Products - 1) + ")", NumericFormat) ' Sum of Sales
Sheet.WriteFormula(TotalRow, 3, "SUM(C" + StartRow + ":C" + (StartRow + Products - 1) + ")", NumericFormat) ' AverageDaily

Product_WriteData = .t.
END FUNCTION

'*************************************************************
' Shared functions to write page and column headings
'*************************************************************

FUNCTION WritePageHeadings as L (Doc as Office::ExcelDocument, Sheet as Office::Spreadsheet, StartRow as N, ColumnSpan as N, Text as C)
    
' Add a title line formatted with Bold 14 point Tahoma font in Blue and merge the first 5 columns in the first row
dim Format as Office::Format ' Pointer to the format for Page headings
dim Font   as Office::Font   ' Pointer to the font for Page headings
dim Lines  as N = w_count(Text, crlf())
dim Row    as N

Format = Doc.AddFormat()
Font = Doc.AddFont()
Font.Color = Office::Color::DarkBlue
Font.Name = "Tahoma"
Font.Size = 14
Font.Bold = .t.
Format.Font = Font    ' Set the font into the page heading format
Format.HorizontalAlignment = Office::HorizontalAlignment::Center
for i = 1 to Lines
        Row = StartRow + i - 1
        HeadingLine = AllTrim(Word(Text, i, crlf()))
        Sheet.SetMerge(Row,Row,1,ColumnSpan)
        Sheet.Write(Row,1,HeadingLine, Format)
next

WritePageHeadings = .t.
END FUNCTION



FUNCTION WriteColumnHeadings as L (Doc as Office::ExcelDocument, Sheet as Office::Spreadsheet, StartRow as N, HeadingDescriptors as C)

dim ColumnHeadingCount as N = w_count(HeadingDescriptors, crlf())

' Add the column headings (row 3)
' Add a title formatted with Bold 14 point Tahoma font in Blue and merge the first 5 columns in the first row
dim LeftFormat        as Office::Format ' Pointer to the left aligned format for Column headings
dim RightFormat       as Office::Format ' Pointer to the right aligned format for Column headings
dim Font              as Office::Font   ' Pointer to the font for Column headings
dim CurrentFormat     as Office::Format
dim CurrentDescriptor as C
dim CurrentHeading    as C
dim CurrentType       as C
dim CurrentLength     as N

Font = Doc.AddFont()
Font.Color = Office::Color::DarkBlue
Font.Name = "Tahoma"
Font.Size = 11
Font.Bold = .t.
LeftFormat = Doc.AddFormat()
LeftFormat.Wrap = .t.
LeftFormat.Font = Font    ' Set the font into the column heading format
LeftFormat.HorizontalAlignment = Office::HorizontalAlignment::Left
RightFormat = Doc.AddFormat()
RightFormat.Wrap = .t.
RightFormat.Font = Font    ' Set the font into the column heading format
RightFormat.HorizontalAlignment = Office::HorizontalAlignment::Right

for i = 1 to ColumnHeadingCount
    CurrentDescriptor = word(HeadingDescriptors, i,crlf())
    
    CurrentHeading = AllTrim(Word(CurrentDescriptor, 1, "|"))
    CurrentType    = AllTrim(Word(CurrentDescriptor, 2, "|"))
    CurrentLength  = Val(AllTrim(Word(CurrentDescriptor, 3, "|")))
    if CurrentLength < 1
        if CurrentType = "$" 
            CurrentLength = len("($ 000,000.00)")
        else if CurrentType = "D"
            CurrentLength = len("00/00/0000")
        else
            CurrentLength = 10
        end if
    end if
    if CurrentType = "$"
        CurrentFormat = RightFormat
    else
        CurrentFormat = LeftFormat
    end if
    Sheet.SetColumn(i, i, max(CurrentLength * 1.2, Sheet.ColumnWidth(i)))
    Sheet.Write(StartRow, i, CurrentHeading, CurrentFormat)
next    

WriteColumnHeadings = .t.
END FUNCTION



'*************************************************************
' Functions to generate sample data
'*************************************************************
FUNCTION GetSalesAndExpenses as L (Date as D, BYREF Sales as N, BYREF Expenses as N)
' This function generates random values

Sales = 2600 + rand() * 500
Expenses = 2500 + rand() * 500    

GetSalesAndExpenses = .t.    
END FUNCTION

FUNCTION GetProductWeeklySales as L (Product as C, Date as D, BYREF Sales as N)
' This function generates random values

Sales = 1500 + rand() * 500
GetProductWeeklySales = .t.    
END FUNCTION

FUNCTION GetProductList as C ()
dim ResultString as C
dim LastValue as N = int(rand() * 1000)
for i = 1 to 100
    LastValue = LastValue + int(rand() * 5)
    ValueString = "" + LastValue
    ResultString = ResultString + "PRD" + Padl(ValueString, 6, "0") + crlf()
next
GetProductList = ResultString
END FUNCTION

See Also