none
Getting the position of Inline Shapes and Shapes. RRS feed

  • Question

  • '****************************************************************
    '********************* Begin Diagnostics() **********************
    '****************************************************************
    
    Public Sub Diagnostics()
        
        'Set this document to the active target
        Documents(thsDoc).Activate
        ActiveDocument.Range.Text = ""
        
        Dim file2Write As Integer
        Dim file2WriteName As String
        Dim tShapes As Shapes
        Dim tInlineShapes As InlineShapes
        
        file2Write = FreeFile()
        file2WriteName = "debugimages.txt"
        Set tShapes = InDoc.Shapes
        Set tInlineShapes = InDoc.InlineShapes
        
        '--------------------------------------------------------------------------
        'Open diagnostics.txt for writing. Diagnositics will be printed to the file.
        '---------------------------------------------------------------------------
        Open file2WriteName For Output As file2Write
        
        
        
        
        
        
        
        
        
        For ShapeCount = 1 To tShapes.Count
            Print #file2Write, "Shape Type: " & Str(tShapes(ShapeCount).Type)
            Print #file2Write, "Shape Height: " & Str(tShapes(ShapeCount).Height)
            Print #file2Write, "Shape Width: " & Str(tShapes(ShapeCount).Width)
            Print #file2Write, "RelativeHorizontal & Str(tShapes(ShapeCount).RelativeHorizontalPosition)
            Print #file2Write, "RelativeVertical & Str(tShapes(ShapeCount).RelativeVerticalPosition)
            Print #file2Write, "ZOrder & Str(tShapes(ShapeCount).ZOrderPosition)
            Print #file2Write, "----------"
        Next ShapeCount
        Print #file2Write, "Shapes count: " & tShapes.Count
        
        
        
        For InlineShapeCount = 1 To tInlineShapes.Count
            Print #file2Write, "InlineShape Type: " & Str(tInlineShapes(InlineShapeCount).Type)
            Print #file2Write, "InlineShape Height: " & Str(tInlineShapes(InlineShapeCount).Height)
            Print #file2Write, "InlineShape Width: " & Str(tInlineShapes(InlineShapeCount).Width)
            'Print #file2Write, "InlineShape Columns: " & Str(tInlineShapes(InlineShapeCount).Range.Columns)
            'Print #file2Write, "InlineShape Rows: " & Str(tInlineShapes(InlineShapeCount).Range.Rows)
            Print #file2Write, "----------"
        Next InlineShapeCount
        Print #file2Write, "InlineShapes count: " & tInlineShapes.Count
        
        
        
        
        
        
        
        
        
        Close #file2Write
        '-------------------------------------------------------------------------
        'Close diagnostics.txt.
        '--------------------------------------------------------------------------
    
    End Sub
    '****************************************************************
    '********************* End Diagnostics() ************************
    '****************************************************************

    My goal here is to get the position of all the InlineShapes and Shapes so that I can then read in the text that comes before and after each Shape and InlineShape. The idea is that once I have the text that comes before and after each Shape and InlineShape I can then copy the shapes into my new document in their relative proper locations for each object.

    My output file looks like this:

    Shape Type:  1
    Shape Height:  20.15
    Shape Width:  362.3
    RelativeHorizontalRelativeVerticalZOrder----------
    Shape Type:  5
    Shape Height:  1
    Shape Width:  362.35
    RelativeHorizontalRelativeVerticalZOrder----------
    Shape Type:  1
    Shape Height:  118
    Shape Width:  134
    RelativeHorizontalRelativeVerticalZOrder----------
    Shape Type:  1
    Shape Height:  25.5
    Shape Width:  538.6
    RelativeHorizontalRelativeVerticalZOrder----------

    InlineShape Type:  3
    InlineShape Height:  2.15
    InlineShape Width:  335.3
    ----------
    InlineShape Type:  3
    InlineShape Height:  3.2
    InlineShape Width:  534.1
    ----------
    InlineShape Type:  3
    InlineShape Height:  3.2
    InlineShape Width:  534.1
    ----------
    InlineShape Type:  3
    InlineShape Height:  2.15
    InlineShape Width:  535.15
    ----------
    InlineShape Type:  3
    InlineShape Height:  2.15
    InlineShape Width:  509.35
    ----------
    InlineShape Type:  3
    InlineShape Height:  2.15
    InlineShape Width:  509.35
    ----------

    I see that there is some locations data available for Shapes and there is a Range selector for InlineShapes. I am not sure however how I am supposed to translate that into a location that will allow me to read into memory the text before and after each object. I apologize I have to bother the forum with this but I'm not sure what else to do with this right now.

    I also see that there is a property for Shapes "Top" that returns points. I think the main question I am asking is this. How am I supposed to convert points to a range starting position? I see that inline shapes are returning a range start and end already so that I can reuse to set a range and then select and read the text around the image.

    Thank you in advance for any comments or answers.

    Kind Regards,

    Sepoto


    P.S. I am going through the developers guide on Word which I really have enjoyed reading so far. I see that perhaps I can select the shape and then use the selection object to get the range and use GoToNext and GoToPrevious to get what is around the object. Is that what needs to happen?
    • Edited by S.e.p.y Thursday, August 30, 2012 7:17 AM Post script.
    Thursday, August 30, 2012 6:16 AM

Answers

  • For an InlineShape, the text you're interested in could be in the same paragraph or a preceding/following paragraph. You can retrieve that text with code like:

    Dim Rng As Range
    With ActiveDocument.Range.InlineShapes(1)
      'Get text before in same para
      Set Rng = .Range.Paragraphs.First.Range
      Rng.End = .Range.Start
      MsgBox Rng.Text
      'Get text after  in same para
      Set Rng = .Range.Paragraphs.First.Range
      Rng.Start = .Range.End
      MsgBox Rng.Text
      'Get text before in previous para
      Set Rng = .Range.Paragraphs.First.Previous.Range
      MsgBox Rng.Text
      'Get text after  in next para
      Set Rng = .Range.Paragraphs.First.Next.Range
      MsgBox Rng.Text
    End With

    For a shape, it's a whole lot more 'interesting'. Whilst it's easy enough to find out about the paragraph the shape is anchored to, finding out about the nearest paragraphs in a layout sense relies on comparing the relative vertical (and, perhaps, horizontal) position of each paragraph on the page against the corresponding data for the shape (including it's width and height, where applicable). On a multi-column page page, this can be a real challenge.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by S.e.p.y Thursday, August 30, 2012 9:19 AM
    Thursday, August 30, 2012 8:19 AM

All replies

  • For an InlineShape, the text you're interested in could be in the same paragraph or a preceding/following paragraph. You can retrieve that text with code like:

    Dim Rng As Range
    With ActiveDocument.Range.InlineShapes(1)
      'Get text before in same para
      Set Rng = .Range.Paragraphs.First.Range
      Rng.End = .Range.Start
      MsgBox Rng.Text
      'Get text after  in same para
      Set Rng = .Range.Paragraphs.First.Range
      Rng.Start = .Range.End
      MsgBox Rng.Text
      'Get text before in previous para
      Set Rng = .Range.Paragraphs.First.Previous.Range
      MsgBox Rng.Text
      'Get text after  in next para
      Set Rng = .Range.Paragraphs.First.Next.Range
      MsgBox Rng.Text
    End With

    For a shape, it's a whole lot more 'interesting'. Whilst it's easy enough to find out about the paragraph the shape is anchored to, finding out about the nearest paragraphs in a layout sense relies on comparing the relative vertical (and, perhaps, horizontal) position of each paragraph on the page against the corresponding data for the shape (including it's width and height, where applicable). On a multi-column page page, this can be a real challenge.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    • Marked as answer by S.e.p.y Thursday, August 30, 2012 9:19 AM
    Thursday, August 30, 2012 8:19 AM
  • Thank you Macropod for the code. It looks like I am going to have to add in some VBA error handling as "Paragraphs.First.Previous.Range" does throw an exception if there is no previous range to look to.


    Thursday, August 30, 2012 10:17 AM
  • True. you'll also need error handling for ".Range.Paragraphs.First.Next.Range", in case you're already at the end of the document. For example:

    Dim Rng As Range
    With ActiveDocument.Range.InlineShapes(1)
      'Get text before in same para
      Set Rng = .Range.Paragraphs.First.Range
      Rng.End = .Range.Start
      MsgBox Rng.Text
      'Get text after  in same para
      Set Rng = .Range.Paragraphs.First.Range
      Rng.Start = .Range.End
      MsgBox Rng.Text
      'Get text before in previous para
      If Not .Range.Paragraphs.First.Previous Is Nothing Then
        'Get text before in previous para
        Set Rng = .Range.Paragraphs.First.Previous.Range
        MsgBox Rng.Text
      End If
      If Not .Range.Paragraphs.First.Next Is Nothing Then
        'Get text after  in next para
        Set Rng = .Range.Paragraphs.First.Next.Range
        MsgBox Rng.Text
      End If
    End With


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Thursday, August 30, 2012 10:25 AM