Consulting

Results 1 to 8 of 8

Thread: ContentControls and EditPaste

  1. #1

    ContentControls and EditPaste

    Hi,

    in one of my documents I've worked a lot with xml mapped content controls. Basically it is a large table with about 40 rows and 11 columns. All cells contain some sort of content Control (date picker, Rich text Control, Combo box Control etc.). Some of these content Controls are mapped to its own xml node. The xml structure goes something like this:

    TableRow[1]
    Date[1]
    Time[1]
    Frequency[1]
    Mode[1]
    Comment[1]

    TableRow[2]
    Date[1]
    Time[1]
    Frequency[1]
    Mode[1]
    Comment[1]

    and so on. We use this as a test protocol at my job. Now sometimes a user wants to copy the information from example row 1 to row 2, and then modify the text within the content controls on row 2.

    Now to the problem. As the user copy pastes the entire row 1, the mapped content controls gets duplicated. When the user then modifies the information on row 2, the information on row 1 also gets changed (since they are mapped to the same xml nodes).

    I have tried to work with the EditPaste function, to try avoid mapped content controls to be duplicated. Basically the function is: "IF the source we are copying is a mapped content Control, THEN just paste the information within the content control rather than the content control itself." This works pretty well when the user copies one cell (one content control) at a time, but it doesn't work when a whole row of 11 different content controls is pasted to another row.

    Can someone give me some tips about how to get around this? Are there more sofisticated ways to do this?

    Best regards, David

  2. #2
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    Sub ScratchMacro()
    'A basic Word macro coded by Greg Maxey
    Dim oCC As ContentControl
      Selection.Paste
      For Each oCC In Selection.Range.ContentControls
        oCC.XMLMapping.Delete
      Next
    lbl_Exit:
      Exit Sub
      
    End Sub
    Greg

    Visit my website: http://gregmaxey.com

  3. #3
    Thanks Greg, I think you're on to something. But I was not clear enough on what I wanted to do. The content Controls on the destination row are already mapped. When I paste row 1 to row 2 I want row 2 to keep its mapping, but get the content of row 1.

    And to make it even more complicated, when pasting to a table you never know how many cells you are pasting to. For example I could copy cell(1,1) to cell(4,11) and then paste it to cell(5,1), so cell(5,1) to cell(8,11) gets overwritten. But I can never know how many cells I overwrite until I've actually pasted the content...

    Sorry if I over-complicate stuff... Tricky situation here..

  4. #4
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    I suppose you could capture the mapping XPath then delete and recreate it, but this could me futile:

    Sub ScratchMacro()
    'A basic Word macro coded by Greg Maxey
    Dim oCC As ContentControl
    Dim arrXPath() As String
    Dim strXpath As String
    Dim lngCC As Long
    Dim strText As String
    Dim oPart As CustomXMLPart
      lngCC = 0
      For Each oCC In Selection.Range.ContentControls
        ReDim Preserve arrXPath(lngCC)
        lngCC = lngCC + 1
        With oCC.XMLMapping
          arrXPath(UBound(arrXPath)) = .XPath
        End With
      Next
      Selection.Paste
      lngCC = 0
      For Each oCC In Selection.Range.ContentControls
        strText = oCC.Range.Text
        Set oPart = ActiveDocument.CustomXMLParts.SelectByID(oCC.XMLMapping.CustomXMLPart.ID)
        With oCC.XMLMapping
          .Delete
          .SetMapping arrXPath(lngCC), , oPart
        End With
        lngCC = lngCC + 1
        oCC.Range.Text = strText
      Next
    lbl_Exit:
       Exit Sub
    End Sub
    Greg

    Visit my website: http://gregmaxey.com

  5. #5
    Yes, this would work perfectly IF the user selects all the cells he/she is intending to paste to, so the whole range is selected when the paste is initiated. But it would not work if only the first cell is selected (I mean, you can paste a whole row even though you only selected the first cell).

    For that reason, I suppose the challenge here is to find out which range will be affected by the paste command, since that is not necessarily the same as the current selection. Does Word have any such functions to tell the future?

    I'm thinking maybe the macro could
    1) paste the content
    2) track what changed
    3) undo the paste
    4) save the mappings of the affected range
    5) paste again and recreate the mappings

    But that seems like an awful lot of trouble...

  6. #6
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    Futile I think.
    Greg

    Visit my website: http://gregmaxey.com

  7. #7
    OK, I spent some time thinking about it. What if I use the EditCopy() function to monitor the selection that is copied. I can for example store how many cells, rows and columns I'm copying. Then I can put some conditions in the EditPaste() function based on that. I think this is a solution to my problem.

    Now the only question is how to transfer the information from EditCopy() to EditPaste(). I'm not so familiar with how public variables work in Word. Can I store for example the range that is copied as a public variable? So that I can access the range in the EditPaste() function?

  8. #8
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    Option Explicit
    Dim m_oRng As Range
    Sub EditCopy()
      Set m_oRng = Selection.Range
      Selection.Copy
    End Sub
    Sub EditPaste()
      If Selection.Range.ContentControls.Count <> m_oRng.ContentControls.Count Then
        'MsgBox "The selected paste target resemble the copied text range."
        Selection.Paste
      Else
        ScratchMacro
      End If
      
    End Sub
    Sub ScratchMacro()
         'A basic Word macro coded by Greg Maxey
        Dim oCC As ContentControl
        Dim arrXPath() As String
        Dim strXpath As String
        Dim lngCC As Long
        Dim strText As String
        Dim oPart As CustomXMLPart
        lngCC = 0
        For Each oCC In Selection.Range.ContentControls
            ReDim Preserve arrXPath(lngCC)
            lngCC = lngCC + 1
            With oCC.XMLMapping
                arrXPath(UBound(arrXPath)) = .XPath
            End With
        Next
        Selection.Paste
        lngCC = 0
        For Each oCC In Selection.Range.ContentControls
            strText = oCC.Range.Text
            Set oPart = ActiveDocument.CustomXMLParts.SelectByID(oCC.XMLMapping.CustomXMLPart.ID)
            With oCC.XMLMapping
                .Delete
                .SetMapping arrXPath(lngCC), , oPart
            End With
            lngCC = lngCC + 1
            oCC.Range.Text = strText
        Next
    lbl_Exit:
        Exit Sub
    End Sub
    Greg

    Visit my website: http://gregmaxey.com

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •