How to toggle data in the word template

Hi @alexey.noskov
I tried to debug and the moved conditions but no luck. All records printed. I have attached the sample code here.

Forum.zip (96.2 KB)

@akondewar As I have already mentioned, SKIPIF field is intended to skip the record in the data source upon executing mail merge. In your case however, you fill SKIPIF field after filling the document with data, so there is nothing to skip at this stage, I mean the value of dataExclude field is filled after filling the table with data. You should either include the dataExclude field into your table data source or fill it before filling the table with data.

Thanks @alexey.noskov for reply.

We are sending dynamic parameters, and that values not present in table records. Like dataExclude=true and Suppressclosedshort=true. But Ordsts and closedshort values are present in the table records.

https://forum.aspose.com/t/how-to-update-dynamic-value-to-mergedfield-if-condition/278592/6

{ SKIPIF { = OR(
    { = AND( 
        { COMPARE { MERGEFIELD isExclude } = "8-All Line Items Received" }, 
		{ COMPARE { MERGEFIELD dataExclude } = "7-Items Received" },
        { COMPARE { MERGEFIELD dataExclude } = "true" })  
    },  
    { = AND(  
        { COMPARE { MERGEFIELD closedshort } = "true" },  
        { COMPARE { MERGEFIELD Suppressclosedshort } = "true" })  
    } )  
} > 0 }

Is there any way to handle this scenario.

@akondewar It is required to fill dataExclude and Suppressclosedshort values in the document before executing mail merge with regions. For example you can use SET field to achieve this. put the SET field outside the region, execute simple mail merge to fill it with data and then use REF field to use the value in the region. For example see the attached simple template and code.

DataTable data = new DataTable("data");
data.getColumns().add("Column1");
data.getColumns().add("Column2");
data.getColumns().add("Column3");
data.getRows().add("true", "This will be excluded", "Some data");
data.getRows().add("false", "This will not be excluded", "Some data");
data.getRows().add("false", "This will not be excluded", "Some another data");

Document doc = new Document("C:\\Temp\\in.docx");
doc.getMailMerge().setUnconditionalMergeFieldsAndRegions(true);

// Fill isExclude field
doc.getMailMerge().execute(new String[] { "isExclude" }, new String[] { "true" });
// Update update field to update REF field.
doc.updateFields();

// Execute mail merge with regions.
doc.getMailMerge().executeWithRegions(data);

doc.save("C:\\Temp\\out.docx");

in.docx (14.1 KB)
out.docx (11.2 KB)

Thanks for solution , but will not implement because we have multiple templates with different format.

Can we use SKIPIF in IF condtion, means If condition is true the execute SKIPIF

I would like to used following condition but it’s not work while 'efl ’ or ‘supcs’ is false in executemail merge

mapAditionalParam = new HashMap<String,Object>();
mapAditionalParam.put("efl", true);
mapAditionalParam.put("supcs", false);
String[] str1 = (String[]) mapAditionalParam.keySet().toArray(new String[mapAditionalParam.size()]);
Object[] obj1 = mapAditionalParam.values().toArray();
doc.getMailMerge().execute(str1, obj1);	

{IF {MERGEFIELD efl \* MERGEFORMAT } = "true" { SKIPIF { MERGEFIELD isExclude } = "true" } }
{IF {MERGEFIELD supcs \* MERGEFORMAT } = "true" { SKIPIF { MERGEFIELD closedshort } = "true" } }

Purchase Order TemplateV4.docx (30.1 KB)

<PrintForm>
	<Vendor_Name>A-CASH-1 (A-CASH-1)</Vendor_Name>
	<Order_Number>32</Order_Number>
	<PO_Order_Total>40.000000</PO_Order_Total>
	<PODetails>
		<isExclude>true</isExclude>
		<Product_Description>Prod1</Product_Description>
		<Product>PO-00032-1</Product>
		<Line_No>1</Line_No>
		<closedshort>true</closedshort>
		<Unit_Price>10.000000</Unit_Price>
		<Product_Quantity>1.000000</Product_Quantity>
	</PODetails>
	<PODetails>
		<isExclude>false</isExclude>
		<Product_Description>Prod1</Product_Description>
		<Product>PO-00032-2</Product>
		<Line_No>2</Line_No>
		<closedshort>false</closedshort>
		<Unit_Price>5.000000</Unit_Price>
		<Product_Quantity>1.000000</Product_Quantity>
	</PODetails>
	<PODetails>
		<isExclude>false</isExclude>
		<Product_Description>Prod3</Product_Description>
		<Product>PO-00032-3</Product>
		<Line_No>3</Line_No>
		<closedshort>true</closedshort>
		<Unit_Price>6.000000</Unit_Price>
		<Product_Quantity>5.000000</Product_Quantity>
	</PODetails>
	<PODetails>
		<isExclude>false</isExclude>
		<Product_Description>Prod4</Product_Description>
		<Product>PO-00032-4</Product>
		<Line_No>4</Line_No>
		<closedshort>false</closedshort>
		<Unit_Price>6.000000</Unit_Price>
		<Product_Quantity>5.000000</Product_Quantity>
	</PODetails>
	
	<PODetails>
		<isExclude>true</isExclude>
		<Product_Description>Prod5</Product_Description>
		<Product>PO-00032-5</Product>
		<Line_No>5</Line_No>
		<closedshort>false</closedshort>
		<Unit_Price>6.000000</Unit_Price>
		<Product_Quantity>5.000000</Product_Quantity>
	</PODetails>
	<PODetails>
		<isExclude>false</isExclude>
		<Product_Description>Prod6</Product_Description>
		<Product>PO-00032-6</Product>
		<Line_No>6</Line_No>
		<closedshort>false</closedshort>
		<Unit_Price>6.000000</Unit_Price>
		<Product_Quantity>5.000000</Product_Quantity>
	</PODetails>
	<PODetails>
		<isExclude>false</isExclude>
		<Product_Description>Prod7</Product_Description>
		<Product>PO-00032-7</Product>
		<Line_No>7</Line_No>
		<closedshort>true</closedshort>
		<Unit_Price>6.000000</Unit_Price>
		<Product_Quantity>5.000000</Product_Quantity>
	</PODetails>
</PrintForm>

@akondewar Yes, this is expected that the approach does not work. The SKIPIF field must be fully evaluated on the time when the row is filled with data to make it work. That is why I have suggested either put the condition field into your data source used to fill the table with data or use SET and REF field to evaluate the condition before executing mail merge with regions.

Hello ,
Even we don’t know which row have ‘isExclude = true / false’ or ‘closedshort = true/false’ in the xml and xml parent tag name because this is custom table.
Then how to set value?
Our condition like this

{IF {MERGEFIELD efl \* MERGEFORMAT } = "true" { SKIPIF { MERGEFIELD isExclude } = "true" } }
{IF {MERGEFIELD supcs \* MERGEFORMAT } = "true" { SKIPIF { MERGEFIELD closedshort } = "true" } }

IF ‘efl’ and 'supcs ’ is true then execute ‘SKIPIF’. We are adding '‘efl’ and 'supcs ’ at runtime using following code

mapAditionalParam = new HashMap<String,Object>();
mapAditionalParam.put("efl", true);
mapAditionalParam.put("supcs", false);
String[] str1 = (String[]) mapAditionalParam.keySet().toArray(new 
String[mapAditionalParam.size()]);
Object[] obj1 = mapAditionalParam.values().toArray();
doc.getMailMerge().execute(str1, obj1);	

Please provide sample code for ’ SET and REF field to evaluate the condition before executing mail merge with regions.

@akondewar I have already provided the example in this post:
https://forum.aspose.com/t/how-to-toggle-data-in-the-word-template/279014/24

both sample template and code are provided.

@alexey.noskov
I have tried given example SET and REF but it’s not work, kindly do the needful.

I have attached sample code, word template file, output file.

Note : Our existing code is common code for multiple locale and custom templates (more than 100+).

04-April-2024.zip (110.3 KB)

@akondewar In your code you fill efl after executing mail merge with regions, so the table is filled before setting the SET field. Please see the example provided above, where the SET field is filled before executing mail merge with regions.

@alexey.noskov Thanks, it’s working for following condition

SET efl  "{MERGEFIELD  efl  \* MERGEFORMAT}"}
SET supcs "{MERGEFIELD  supcs  \* MERGEFORMAT}"}

{ SKIPIF { = OR(
    { = AND( 
             { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "8-All Line Items Received" }, 
	     { COMPARE "{REF efl }" = "true"})  
    },  
    { = AND(  
        { COMPARE { MERGEFIELD closedshort } = "true" },  
        { COMPARE { REF supcs } = "true" })  
    }) 
} > 0 }

But while adding one more Compare then it’s not working, that is { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "7-Items Received" },

SET efl  "{MERGEFIELD  efl  \* MERGEFORMAT}"}
SET supcs "{MERGEFIELD  supcs  \* MERGEFORMAT}"}

{ SKIPIF { = OR(
    { = AND( 
             { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "8-All Line Items Received" }, 
	     **{ COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "7-Items Received" },** 
	     { COMPARE "{REF efl }" = "true"})  
    },  
    { = AND(  
        { COMPARE { MERGEFIELD closedshort } = "true" },  
        { COMPARE { REF supcs } = "true" })  
    }) 
} > 0 }

@akondewar { MERGEFIELD isExclude \*MERGEFORMAT } is also filled after executing mail merge with regions. That is why it does not work. You should use the same SET/REF fields approach for this field.

@alexey.noskov
Ok, but how it’s working fine while using following codtion without using SET REF for 'isExclude ’

SET efl  "{MERGEFIELD  efl  \* MERGEFORMAT}"}
SET supcs "{MERGEFIELD  supcs  \* MERGEFORMAT}"}

{ SKIPIF { = OR(
    { = AND( 
             { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "8-All Line Items Received" }, 
	     { COMPARE "{REF efl }" = "true"})  
    },  
    { = AND(  
        { COMPARE { MERGEFIELD closedshort } = "true" },  
        { COMPARE { REF supcs } = "true" })  
    }) 
} > 0 }

Actually ‘isExclude’ value is present in the table row(input xml file).

I have attached Sample code and Word Template file.

Purchase Order TemplateV9.docx is working fine

Kindly check the code and template file
SampleCode_04-April-2024.zip (53.8 KB)

@akondewar As I can see everything works as expected with Purchase Order TemplateV9.docx template and the following simple code:

Document doc = new Document("C:\\Temp\\Purchase Order TemplateV9.docx");
        
doc.getMailMerge().execute(new String[] { "efl","supcs" }, new String[]{ "true", "true" });
doc.updateFields();
        
DataSet ds = new DataSet();
ds.readXml("C:\\Temp\\input_v3.xml");
doc.getMailMerge().executeWithRegions(ds);
        
doc.save("C:\\Temp\\out.docx");

@alexey.noskov Yes I know,working fine for TemplateV9.docx. But its not working as espected for ‘Purchase Order TemplateV10.docx’

Condition in '‘Purchase Order TemplateV10.docx’ :

SET efl  "{MERGEFIELD  efl  \* MERGEFORMAT}"}
SET supcs "{MERGEFIELD  supcs  \* MERGEFORMAT}"}

{ SKIPIF { = OR(
    { = AND( 
             { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "8-All Line Items Received" }, 
			 { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "7-Items Received" }, 
			 { COMPARE "{REF efl }" = "true"})  
    },  
    { = AND(  
        { COMPARE { MERGEFIELD closedshort } = "true" },  
        { COMPARE { REF supcs } = "true" })  
    }) 
} > 0 }

@akondewar As I have mentioned earlier AND function accepts only two parameters. In your syntax, however, there are three parameters.

{ = AND( 
    { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "8-All Line Items Received" }, 
    { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "7-Items Received" }, 
    { COMPARE "{REF efl }" = "true"})  
}

Also, there cannot be situation when isExclude field value simultaneously equals two different values.

@alexey.noskov Thanks,
Attached word templates is working fine while executing through eclipse, but not on Linux server (java version 1.7).

Purchase_Order_Template_v2.docx (Without SET,REF)
Purchase Order TemplateV9.docx( Using SET,REF)

Kindly do the needful.

Purchase_Order_Template_v2.zip (53.7 KB)

@akondewar Unfortunately, I do not see what can be done from our side. I can only suggest the flowing:

  1. Please make sure you are using the same templates, data, code and Aspose.Words version in both your test and production environments.
  2. Try simplifying the template and data to make it easier to debug.
  3. Try adding fields that shows the values passed to SKIPIF to make sure they are evaluated correctly.

@alexey.noskov Thanks for reply, I found the following RCA :

We are using multiple locales.

Following condition is not working while we set 'CurrentThreadSettings.setLocale(“pl_PL”) / de-AT etc.

It is working fine while locale is ‘en_US’

Our condition in the template :

SET efl  "{MERGEFIELD  efl  \* MERGEFORMAT}"}
SET supcs "{MERGEFIELD  supcs  \* MERGEFORMAT}"}

{ SKIPIF { = OR(
    { = AND( 
             { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "8-All Line Items Received" }, 
			 { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "7-Items Received" }, 
			 { COMPARE "{REF efl }" = "true"})  
    },  
    { = AND(  
        { COMPARE { MERGEFIELD closedshort } = "true" },  
        { COMPARE { REF supcs } = "true" })  
    }) 
} > 0 }

@akondewar The provided condition is not quite correct. AND function accepts only two parameters. In your syntax, however, there are three parameters.

{ = AND( 
    { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "8-All Line Items Received" }, 
    { COMPARE "{ MERGEFIELD isExclude \*MERGEFORMAT } = "7-Items Received" }, 
    { COMPARE "{REF efl }" = "true"})  
}

Also, there cannot be situation when isExclude field value simultaneously equals two different values. So this condition, even if there was not a syntax error, is always false.

You can check this using the following simple field { =AND(1,0,1) } this will return syntax error because AND accepts only two parameters. { =AND(1,0) } will return 0, i.e. false.