Hi,
I am getting the exception “The newChild was created from a different document than the one that created this node.”
We have Report where we use more than one relationship to display the data and this will be generated in 3 formats PDF, HTML and Word.
we are using following software.
Visual Studio : 2005
Dotnet Frame work:2.0
Template:Microsoft word 2007
Aspose.words version:8.2.0.0(Trial)
The following code is part of the main function
#Region " Sub : GenerateDocument "
Public Overrides Sub GenerateDocument()
If Me.TemplatePath Is Nothing OrElse Me.TemplatePath.Trim.Equals("") Then
Throw New Exception("Template path not set.")
End If
' set license
Dim licenseFile As String = ConfigurationSettings.AppSettings("AsposeLicenseFile")
If (Not licenseFile Is Nothing) AndAlso (Not String.Empty.Equals(licenseFile)) Then
If Not Me.HttpContext Is Nothing Then
' called from webui; map virtual path to physical path
licenseFile = Me.HttpContext.Server.MapPath(Me.HttpContext.Request.ApplicationPath & licenseFile)
End If
Dim asposeWordLicense As New Aspose.Words.License
asposeWordLicense.SetLicense(licenseFile)
Dim asposePdfLicense As New Aspose.Pdf.License
asposePdfLicense.SetLicense(licenseFile)
'Added by Arvind for EXCEL
Dim asposeExcelLicense As New Aspose.Excel.License
asposeExcelLicense.SetLicense(licenseFile)
'End
End If
' Create new document from the Template
Dim document As Aspose.Words.Document
Dim designer As ExcelDesigner
Try
If Not Me.OutputType = OutputType.EXCEL Then
document = New Aspose.Words.Document(Me.TemplatePath)
End If
If Me.OutputType = OutputType.EXCEL Then
designer = New ExcelDesigner
Dim designerFile As String = Me.TemplatePath
designer.Open(designerFile)
End If
''End
Catch ex As System.ObjectDisposedException
' ignore ObjectDisposedException error
End Try
' set repetitive fields
If Me.Relation Is Nothing AndAlso (Me.Relations Is Nothing OrElse Me.Relations.Count = 0) Then
' No master- child relation
Dim enumerator As IDictionaryEnumerator = Me.DocumentTableList.GetEnumerator()
While enumerator.MoveNext
Dim dataTable As System.Data.DataTable = enumerator.Value
If Not Me.OutputType = OutputType.EXCEL Then
document.MailMerge.ExecuteWithRegions(dataTable)
End If
If Me.OutputType = OutputType.EXCEL Then
designer.SetDataSource(dataTable)
designer.SetDataSource(Me.StaticFieldsList)
End If
'end
End While
ElseIf (Not Me.Relations Is Nothing) AndAlso (Me.Relations.Count > 1) Then
If Not Me.OutputType = OutputType.EXCEL Then
Dim dstDoc As Aspose.Words.Document = document.Clone()
dstDoc.Sections.Clear()
Me.IsFirstPage = True
For Each relation As DataRelation In Me.Relations
ProcessRelation(relation, document, dstDoc)
Next
InsertHeader(dstDoc)
document = dstDoc
End If
If Me.OutputType = OutputType.EXCEL Then
ProcessExcelRelations(Me.Relation, designer)
End If
'End
ElseIf Not Me.Relation Is Nothing Then
If Not Me.OutputType = OutputType.EXCEL Then
Dim dstDoc As Aspose.Words.Document = document.Clone()
dstDoc.Sections.Clear()
ProcessRelation(Me.Relation, document, dstDoc)
InsertHeader(dstDoc)
document = dstDoc
End If
If Me.OutputType = OutputType.EXCEL Then
ProcessExcelRelation(Me.Relation, designer)
End If
End If
' set static fields
If Not Me.StaticFieldsList Is Nothing Then
If Not Me.OutputType = OutputType.EXCEL Then
If document.Sections.Count.Equals(0) Then
Throw New Exception(Constants.NoRecordsFound)
End If
document.MailMerge.Execute(Me.StaticFieldsList)
End If
End If
Select Case Me.SaveType
Case SaveType.Save
If Not Me.OutputType = OutputType.EXCEL Then
Save(document, Me.OutputType)
End If
If Me.OutputType = OutputType.EXCEL Then
SaveExcel(designer)
End If
'end
Case SaveType.Browser
If Not Me.OutputType = OutputType.EXCEL Then
SendToBrowser(document, Me.OutputType)
End If
If Me.OutputType = OutputType.EXCEL Then
SaveExcel(designer)
End If
'end
Case SaveType.SaveAndBrowser
If Not Me.OutputType = OutputType.EXCEL Then
Save(document, Me.OutputType)
SendToBrowser(document, Me.OutputType)
End If
If Me.OutputType = OutputType.EXCEL Then
SaveExcel(designer)
End If
'end
End Select
End Sub
#End Region
#Region " Sub : ProcessRelation "
Protected Sub ProcessRelation(ByRef relation As DataRelation, ByRef document As Aspose.Words.Document, ByRef dstDoc As Aspose.Words.Document)
' master-child tables
Dim parentTable As DataTable = relation.ParentTable Dim builder As DocumentBuilder
' get all child relations for this table
For Each childRelation As DataRelation In Me.Relations
If parentTable Is childRelation.ParentTable Then
' exclude all child relation, bcos child reltions will be processed recursively
If Not IsChildRelation(childRelation) Then
For Each parentRow As DataRow In parentTable.Rows
If (parentRow.GetChildRows(childRelation).Length > 0) Then
If Not Me.IsFirstPage Then
InsertPageBreak(dstDoc)
Else
Me.IsFirstPage = False
End If
End If
ProcessParentRow(parentRow, childRelation, parentTable, document, dstDoc)
Next
End If
End If
Next
End Sub
#End Region
#Region " Function : ProcessParentRow "
Private Sub ProcessParentRow(ByRef parentRow As DataRow, ByRef childRelation As DataRelation,
ByRef parentTable As DataTable, ByRef document As Aspose.Words.Document,
ByRef dstDoc As Aspose.Words.Document)
If parentRow.GetChildRows(childRelation).Length > 0 Then
' Each parent record needs a complete copy of the template.
' Making a copy in memory is much faster than opening the document every time from a file.
Dim parentSectionNumber As String = GetSectionNumber(childRelation)
Dim parentRecordDoc As Aspose.Words.Document = GetDocumentSection(document, parentSectionNumber)
' no header for HTML
If Me.OutputType = OutputType.HTML Then
If parentRecordDoc.Sections.Count > 0 Then
parentRecordDoc.Sections(0).ClearHeadersFooters()
End If
End If
' fill parent record fields using normal mail merge.
parentRecordDoc.MailMerge.Execute(parentRow)
'add generated parent record document to the complete report.
'AppendDoc(dstDoc, parentRecordDoc)
' Retrieve child records for this parent & fill table in the report.
Dim childTable As DataTable childTable = childRelation.ChildTable.Clone
childTable.Rows.Clear()
For Each childRow As DataRow In parentRow.GetChildRows(childRelation)
childTable.Rows.Add(childRow.ItemArray)
Next
If Me.NestedRelation Then
Dim nextRelation As DataRelation = GetNextRelation(childRelation)
If nextRelation Is Nothing Then
' next relation not found, process child records
'Dim childSectionNumber As String = GetSectionNumber(childRelation, True)
'Dim childRecordDoc As Aspose.Words.Document = GetDocumentSection(document, childSectionNumber)
'childRecordDoc.MailMerge.ExecuteWithRegions(childTable)
'AppendDoc(dstDoc, childRecordDoc)
parentRecordDoc.MailMerge.ExecuteWithRegions(childTable)
' merge summary for child table
parentRecordDoc.MailMerge.ExecuteWithRegions(GetSummaryTable(childTable))
AppendDoc(dstDoc, parentRecordDoc)
Else
'First Append Parent Record
AppendDoc(dstDoc, parentRecordDoc)
' next relation found, recursively process next relation
SetChildTableForRelation(nextRelation, childTable)
Dim nextTable As DataTable = nextRelation.ParentTable
For Each nextTableRow As DataRow In nextTable.Rows
ProcessParentRow(nextTableRow, nextRelation, nextTable, document, dstDoc)
Next
End If
Else
parentRecordDoc.MailMerge.ExecuteWithRegions(childTable)
parentRecordDoc.MailMerge.ExecuteWithRegions(GetSummaryTable(childTable))
'The last thing to do is to add just generated parent record document to the complete report.
AppendDoc(dstDoc, parentRecordDoc)
End If
End If
End Sub
#End Region
#Region " Function : GetDocumentSection "
Private Function GetDocumentSection(ByRef document As Aspose.Words.Document, ByVal sectionNumber As String) As Aspose.Words.Document
If String.Empty.Equals(sectionNumber & "") Then
Return document.Clone()
End If
Dim result As New Aspose.Words.Document
For Each relation As DataRelation In Me.Relations
If relation.ExtendedProperties("SectionNumber") = sectionNumber Then
Dim section As Section = document.Sections(sectionNumber)
result.Sections.Clear()
'result.Sections.Insert(0, document.Sections(sectionNumber).Clone())
result.Sections.Add(section) '' ExceptionThe newChild was created from a different document than the one that created this node.
End If
Next
Return result
End Function
#End Region
#Region " Function : GetSectionNumber "
Public Function GetSectionNumber(ByRef relation As DataRelation, Optional ByVal lastSection As Boolean = False) As String Dim key As String If lastSection Then
key = "LastSectionNumber"
Else
key = "SectionNumber"
End If
If relation.ExtendedProperties.ContainsKey(key) Then
Return relation.ExtendedProperties(key).ToString()
End If
Return String.Empty
End Function
#End Region
#Region " Function : GetNextRelation "
Public Function GetNextRelation(ByRef parentRelation As DataRelation) As DataRelation
Dim result As DataRelation
If parentRelation.ExtendedProperties.ContainsKey("NextRelation") Then
result = parentRelation.ExtendedProperties("NextRelation")
End If
Return result
End Function
#End Region
#Region " Sub : AppendDoc "
Private Sub AppendDoc(ByVal dstDoc As Aspose.Words.Document, ByVal srcDoc As Aspose.Words.Document)
While srcDoc.Sections.Count > 0
Dim section As Section = srcDoc.Sections(0)
'The section must first be removed before it can be inserted into a document.
srcDoc.Sections.RemoveAt(0)
dstDoc.Sections.Add(section)
End While
End Sub
#End Region
#Region " Sub : ProcessExcelRelations "
Protected Sub ProcessExcelRelations(ByRef relation As DataRelation, ByRef document As ExcelDesigner) ', ByRef dstDoc As Aspose.Excel.Worksheet)
Dim parentTable As DataTable = relation.ParentTable
Dim PrntTable As New DataTable PrntTable = relation.ParentTable.Clone
PrntTable.Clear()
Dim ChdTable As New DataTable ChdTable = relation.ChildTable.Clone
For Each row As DataRow In parentTable.Rows
Dim dr As DataRow() = parentTable.Select(row(relation.ParentColumns(0).ColumnName))
PrntTable.Rows.Add(dr)
document.SetDataSource(PrntTable)
ChdTable.Clear()
For Each childRow As DataRow In row.GetChildRows(relation)
ChdTable.Rows.Add(childRow.ItemArray)
Next
If Me.NestedRelation Then
RecursiveFunctionForExcel(document, ChdTable, relation)
End If
Next
End Sub
#End Region
#Region "RecursiveFunctionForExcel"
Private Sub RecursiveFunctionForExcel(ByRef document As ExcelDesigner, ByRef parenttbl As DataTable, ByRef relation As DataRelation)
Dim nextRelation As DataRelation = Me.GetNextRelation(relation)
Dim newRelation As New DataRelation(nextRelation.RelationName, nextRelation.ParentTable.Columns(nextRelation.ParentColumns(0).ColumnName), parenttbl.Columns(nextRelation.ChildColumns(0).ColumnName))
Dim secondchildtable As DataTable = newRelation.ParentTable For Each row1 As DataRow In secondchildtable.Rows
Dim nextPrntTable As DataTable = newRelation.ParentTable.Clone
Dim dr As DataRow() = secondchildtable.Select(row1(newRelation.ParentColumns(0).ColumnName))
nextPrntTable.Rows.Add(dr)
document.SetDataSource(nextPrntTable)
Dim mainTable As New DataTable mainTable = newRelation.ChildTable.Clone
mainTable.Clear()
For Each childRow As DataRow In row1.GetChildRows(newRelation)
mainTable.Rows.Add(childRow.ItemArray)
Next
If Not Me.GetNextRelation(nextRelation) Is Nothing Then
RecursiveFunctionForExcel(document, mainTable, nextRelation)
Else
document.SetDataSource(mainTable)
If Not Me.StaticFieldsList Is Nothing Then
If Not Me.ColumnsCount Is Nothing Then
Dim iEnum As IDictionaryEnumerator = Me.ColumnsCount.GetEnumerator
While iEnum.MoveNext()
Dim columnName As String = CType(iEnum.Value, String)
Dim templateColumnName As String = CType(iEnum.Key, String)
Dim myTotCount As DataColumn = mainTable.Columns.Add("myTotCount")
myTotCount.Expression = "count(columnName)"
document.SetDataSource(templateColumnName, New String(mainTable.Rows(0)("myTotCount").ToString))
mainTable.Columns.Remove(myTotCount.ColumnName)
End While
End If
If Not Me.ColumnsSum Is Nothing Then
Dim iEnum As IDictionaryEnumerator = Me.ColumnsSum.GetEnumerator
While iEnum.MoveNext()
Dim columnName As String = CType(iEnum.Value, String)
Dim templateColumnName As String = CType(iEnum.Key, String)
Dim myTotCount As DataColumn = mainTable.Columns.Add("myTotCount")
myTotCount.Expression = "sum(columnName)"
document.SetDataSource(templateColumnName, New String(mainTable.Rows(0)("myTotCount").ToString))
mainTable.Columns.Remove(myTotCount.ColumnName)
End While
End If
End If
End If
Next
End Sub
#End Region