duplication de lignes dans une table hiérarchique
Bonjour à tous,
Voilà, je ne parviens pas à dupliquer une ligne et ses lignes enfants dans une table hiérarchique.
Contexte :
Dans une bdd Access 2010, une table "tbElements" contient une arborescence d'Elements hiérarchisés gràce à une colonne "Id" (Long / autoincrémenté) et une colonne "IdParent" (Long).
Pour chaque ligne, la colonne "IdParent" contient l' "Id" de la ligne parente (0 si elle est à la racine).
Je souhaite pouvoir dupliquer une ligne avec ou sans ses lignes enfants, selon le choix de l'utilisateur.
Cette table est le datasource d'un Treelist de DevExpress.
Le déclenchement de la copie d'une ligne se fait par drag&drop + touche Ctrl.
Voici la procédure lancée sur l'évènnement Drop :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
Friend Sub subElements_Copy(ByVal vNode As TreeListNode,
ByVal vTargetNode As TreeListNode)
Try
' Get Elements data
Dim vTree As TreeList = frmExplorer.treeExplorer
Dim vNodeName As String = Convert.ToString(vNode.GetValue(frmExplorer.colGeneralName))
Dim vNodeType As String = Convert.ToString(vNode.GetValue(frmExplorer.colType))
Dim vTargetName As String = Convert.ToString(vTargetNode.GetValue(frmExplorer.colGeneralName))
Dim vTargetType As String = Convert.ToString(vTargetNode.GetValue(frmExplorer.colType))
' Ask to the user if he wants to perform the copy of the children of
' the copied Element also
Dim vRepCopyChildren As DialogResult
vRepCopyChildren = XtraMessageBox.Show(
"You are about to copy the [" & vNodeName & "] " & vNodeType & _
"into the [" & vTargetName & "] " & vTargetType & " !" & _
vbCrLf & vbCrLf & "Do you want to copy its sub-Elements too ?",
"Copy the selected Element into the targeted new Parent Element",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question)
If vRepCopyChildren = DialogResult.Cancel Then Exit Sub
vTree.OptionsBehavior.EnableFiltering = False
' Copy Element with or without its children Elements
Dim vSourceNodeId As Long = Convert.ToInt64(vNode.GetValue(frmExplorer.colId))
Dim vTargetNodeId As Long = Convert.ToInt64(vTargetNode.GetValue(frmExplorer.colId))
Dim vNewNodeId As Long
If vRepCopyChildren = DialogResult.Yes Then
' Copy Element WITH its children Elements
vNewNodeId = fncDALElements_CopyElement_Recursive(vSourceNodeId, vTargetNodeId, True)
ElseIf vRepCopyChildren = DialogResult.No Then
' Copy Element WITHOUT its children Elements
vNewNodeId = fncDALElements_CopyElement_Recursive(vSourceNodeId, vTargetNodeId, False)
End If
' Refresh treeExplorer datasource
'frmExplorer.vDS.DS.Tables("tbElements").Rows.Clear()
'frmExplorer.vDS.DA.Fill(frmExplorer.vDS.DS, "tbElements")
frmExplorer.treeExplorer.RefreshDataSource()
vTree.OptionsBehavior.EnableFiltering = True
' Set the new Element Node focused
Dim vNewNode As TreeListNode = vTree.FindNodeByKeyID(CInt(vNewNodeId))
vNewNode.Selected = True
' Display message : Element succesfully copied !
XtraMessageBox.Show("The [" & vNodeName & "] " & vNodeType & " " & _
"has been succesfully copied" & _
vbCrLf & "into the [" & vTargetName & "] " & vTargetType & _
vbCrLf & "as [" & vNodeName & "]",
"Copy an Element",
MessageBoxButtons.OK,
MessageBoxIcon.Information)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub |
Et la fonction de duplication (récursive pour les lignes enfants si demandé) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
Friend Function fncDALElements_CopyElement_Recursive(ByVal vElementId As Long,
ByVal vNewParentId As Long,
ByVal vCopyChildren As Boolean) _
As Long
Try
Dim vTbElements As DataTable = frmExplorer.vDS.DS.Tables("tbElements")
' Find the Element row to be copied
Dim vELRow() As DataRow = vTbElements.Select("Id = " & vElementId)
' Find the target Parent Element row
Dim vParRow() As DataRow = vTbElements.Select("Id = " & vNewParentId)
' Create the new Element row
Dim vNewELRow As DataRow = vTbElements.NewRow
' Copy all of its data from vElRow
Dim vColumnIndex As Integer
Dim vColId As Integer
Dim vColIdParent As Integer
Dim vColIdProject As Integer
Dim vColIsAssigned As Integer
Dim vColGeneralName As Integer
For Each vColumn As DataColumn In vTbElements.Columns
vColumnIndex = vColumn.Ordinal
Select Case vColumn.ColumnName
Case "Id"
vColId = vColumn.Ordinal
Case "IdParent"
vColIdParent = vColumn.Ordinal
Case "IdProject"
vColIdProject = vColumn.Ordinal
Case "IsAssigned"
vColIsAssigned = vColumn.Ordinal
Case "GeneralName"
vColGeneralName = vColumn.Ordinal
End Select
If vColumn.ColumnName <> "Id" Then
vNewELRow(vColumn.ColumnName) = vELRow(0)(vColumnIndex)
End If
Next
' Update some specific data according to vParRow
'vNewELRow("Id") = DBNull.Value
vNewELRow("GeneralName") = "Copy of " & Convert.ToString(vELRow(0)(vColGeneralName))
vNewELRow("IdParent") = vParRow(0)(vColId)
vNewELRow("IdProject") = vParRow(0)(vColIdProject)
vNewELRow("IsAssigned") = vParRow(0)(vColIsAssigned)
vNewELRow("IsStructural") = False
Dim vTime As Date = Now
vNewELRow("Date_CreatedOn") = vTime
vNewELRow("Date_ModifiedOn") = vTime
' Add vNewElRow into vTbElements
vTbElements.Rows.Add(vNewELRow)
frmExplorer.vDS.DA.Update(vTbElements)
vTbElements.Rows.Clear()
frmExplorer.vDS.DA.Fill(vTbElements)
' Get the Id of the newly created Element
Dim vRows() As DataRow = vTbElements.Select("", "Id DESC")
Dim vNewRowId As Long = Convert.ToInt64(vRows(0)(vColId))
' Copy Children Elements if required and exist
Dim vChildrenRows() As DataRow
vChildrenRows = vTbElements.Select("IdParent = " & vELRow(0)(vColId).ToString)
If vCopyChildren And vChildrenRows.Count > 0 Then
Dim vNewChildElementId As Long
Dim vChildElementId As Long
For nRow As Integer = 0 To vChildrenRows.GetUpperBound(0)
vChildElementId = Convert.ToInt64(vChildrenRows(nRow)(vColId))
vNewChildElementId = fncDALElements_CopyElement_Recursive(vChildElementId, vNewRowId, vCopyChildren)
Next
End If
' Return the Id of the newly created Element
Return vNewRowId
Catch ex As Exception
MsgBox(ex.ToString)
Return Nothing
End Try
End Function |
Lorsque l'action de duplication est déclenchée, j'obtiens l'erreur suivante :
Citation:
System.Data.RowNotInTableException: cette ligne a été supprimée d'une table et ne contient pas de données. BeginEdit() permettra la création de nouvelles données dans cette ligne.
Cette erreur se produit au niveau de la ligne de code :
Code:
1 2
|
vChildrenRows = vTbElements.Select("IdParent = " & vELRow(0)(vColId).ToString) |
Ca fait 2 jours que je tourne en rond sans trouver d'où vient le pb ni de solution.
Si une ame charitable pouvait m'indiquer la bonne direction, ce serait sympa...