DataTplCalcOps.vb
''
'' This code is part of Document Solutions for Word demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System.Globalization
Imports GrapeCity.Documents.Word

'' This example demonstrates the available binary and unary operators
'' that can be used with the 'calc' report templates feature
'' to perform various operations on data.
'' For example, to insert the remainder of the division of two data fields,
'' the template '{{calc ds.a Mod ds.b)}}' can be used.
'' The data source used in this demo contains a single record
'' with random decimal and string values.
Public Class DataTplCalcOps
    Function CreateDocx() As GcWordDocument
        Dim rnd = Util.NewRandom()
        Dim [next] As Func(Of Decimal) =
            Function()
                Return New Decimal(Math.Round(CDbl(rnd.Next(1, 1000000)) / rnd.Next(1, 100), 2))
            End Function

        '' Generate a sample data source with a single record of random data:
        Dim data =
        {
            New With {.a = [next](), .b = [next](), .ta = Util.LoremIpsumWord(), .tb = Util.LoremIpsumWord()}
        }

        Dim doc = New GcWordDocument()

        '' Add the data source:
        doc.DataTemplate.DataSources.Add("ds", data)
        Dim paras = doc.Body.Paragraphs

        '' Styles and templates to show results:
        Dim bulletListTemplate = doc.ListTemplates.Add(BuiltInListTemplateId.BulletDefault, "bulletListTemplate")
        Dim exStyle = doc.Styles(BuiltInStyleId.Heading3)
        exStyle.ParagraphFormat.TabStops.Add(130)
        exStyle.ParagraphFormat.TabStops.Add(260)
        Dim resStyle = doc.Styles(BuiltInStyleId.Strong)

        Dim add As Action(Of String, String) =
            Sub(caption, expr)
                '' Four zero-width spaces are inserted after the opening brace to prevent template expansion:
                paras.Add(caption + vbTab + expr.Insert(1, New String(ChrW(&H200B), 4)) + ":" + vbTab, exStyle).ListFormat.Template = bulletListTemplate
                paras.Last.GetRange().Runs.Add(expr, resStyle)
            End Sub

        add("Data", "{{ds.a}}")
        add("Data", "{{ds.b}}")
        add("Data", "{{ds.ta}}")
        add("Data", "{{ds.tb}}")

        add("Add", "{{calc ds.a + ds.b}}")
        add("Subtract", "{{calc ds.a - ds.b}}")
        add("Multiply", "{{calc ds.a * ds.b}}")
        add("Divide", "{{calc ds.a / ds.b}}")
        add("Modulus", "{{calc ds.a Mod ds.b}}")
        add("Concatenate", "{{calc ds.ta & ds.tb}}")
        add("Equal", "{{calc ds.a = ds.b}}")
        add("Not equal", "{{calc ds.a <> ds.b}}")
        add("Greater than", "{{calc ds.a > ds.b}}")
        add("Greater or equal", "{{calc ds.a >= ds.b}}")
        add("Less than", "{{calc ds.a < ds.b}}")
        add("Less or equal", "{{calc ds.a <= ds.b}}")
        add("Logical And", "{{calc ds.a And ds.b}}")
        add("Logical Or", "{{calc ds.a Or ds.b}}")
        add("Logical Not", "{{calc Not ds.a}}")

        '' Process the templates:
        doc.DataTemplate.Process(CultureInfo.GetCultureInfo("en-US"))

        '' Add a short note describing the demo at the top of the document:
        paras.Insert(
            "This example demonstrates the available binary and unary operators " +
            "that can be used with the 'calc' report templates feature " +
            "to perform various operations on data." +
            "For example, to insert the remainder of the division of two data fields, " +
            "the template '{{calc ds.a Mod ds.b)}}' can be used. " +
            "The data source used in this demo contains a single record " +
            "with random decimal and string values. " +
            "Please see this example's source code for full details.",
            InsertLocation.Start)
        paras.Insert("Report templates: calc operators", doc.Styles(BuiltInStyleId.Heading1), InsertLocation.Start)

        '' Done:
        Return doc
    End Function
End Class