PDA

View Full Version : Query regarding macro working on a 'Selection'



Tecnik
05-08-2006, 04:15 AM
Hi there,

I have a macro that I trying to get working on a 'selection'.
Here's the code:-
Sub main2()
Set myDocument = ActiveDocument

pointsArray = myDocument.Shapes(1).Nodes.Item(1).Points

currXvalue = pointsArray(1, 1)
currYvalue = pointsArray(1, 2)
MsgBox "X= " & currXvalue & Chr(13) _
& "Y= " & currYvalue
.SetPosition 1, (currXvalue + 10), (currYvalue + 10)
End Sub
If I create a new document, draw a line on it, and run the macro, it works ok.
I've been trying to take it one step further so I can click on a line on the page and run the macro and it alters the selection.
I've tried to apply the methodology below, to the above:-

Selection.ShapeRange.Nodes.SetPosition 1, currXvalue + 10, currYvalue + 10
So far I keep coming up against a 'type mismatch' error, can someone help please.

Thanks,

Nick

Killian
05-09-2006, 06:03 AM
Hi Nick,

The trick with working with the selection object is to test to see what it is before running code that may error on the wrong kind of object.
So in the case of manipulating a line, first test to see if the selection is a shape, then see if that shape is a lineWith Selection
If .Type = wdSelectionInlineShape Or _
.Type = wdSelectionShape Then
If .ShapeRange.Type = msoLine Then
'do stuff with the nodes/points
End If
End If
End With

Regarding the Type mismatch:
You were expecting the code from VBA help to actually run, weren't you... :doh:
This is a bit strange - I've found any expression using "Points" results in a Type Mismatch.
The Points result is a 2-d array of singles - I can see them in the watch window as properties of the shape, but the corresponding expression doesn't work.
I'll have to have a think about that...

Tecnik
05-09-2006, 07:19 AM
Hi Killian,

Thanks for the help, it's much appreciated.

I've had a quick play around with the code however I'm kinda lost.

I tried something simple like:-
Sub moveNode1Right10()
With Selection
If .Type = wdSelectionInlineShape Or _
.Type = wdSelectionShape Then
If .ShapeRange.Type = msoLine Then
'do stuff with the nodes/points
MsgBox "line found"
End If
End If
End With
End Sub

However, when I try this nothing happens. Once I've done the checks I need to get the coordinates of the line to be able to manipulate them, I'd been trying:-
Set myDocument = ActiveDocument
pointsArray = Selection.ShapeRange.Nodes.Item(1).Points
that's when I got the 'type mismatch'

If you take a blank document, draw a line on it, and then run this macro, it work's fine and a message box, with the coordinates for node 1, pops up.

Sub moveNode1Right10_COPY()
Set myDocument = ActiveDocument

pointsArray = myDocument.Shapes(1).Nodes.Item(1).Points

currXvalue = pointsArray(1, 1)
currYvalue = pointsArray(1, 2)

MsgBox "X= " & currXvalue & Chr(13) _
& "Y= " & currYvalue

End Sub

I'm trying to do the same thing but rather than referencing the line like this:-
Set myDocument = ActiveDocument
pointsArray = myDocument.Shapes(1).Nodes.Item(1).Points
I'm trying to do something like this:-
pointsArray = Selection.Shapes(1).Nodes.Item(1).Points

I'll keep trying with the code you supplied but I'd be grateful if you could enlighten me further.

Thanks again Killian,

Nick

Killian
05-09-2006, 08:07 AM
However, when I try this nothing happens.You should step though the code line by line (F8) and check which condition isn't being met - when I select a line and run it, I get the msgbox...

And back with the other issues, I think the problem is to do with the interpretation of the Selection object compared with an explicitly named/indexed shape.
It all seems quite tempermental, so I took the two routines you posted last, which were working independantly, and called one from the other.

This is working for meSub main()

Dim shp As Object

With Selection
If .Type = wdSelectionInlineShape Or _
.Type = wdSelectionShape Then
If .ShapeRange.Type = msoLine Then
' set the object variable the the
' 1st (only) shape in the selection
Set shp = Selection.ShapeRange(1)
' call the other routine, passing
' it the object as it's argument
moveNode1Right10 shp
End If
End If
End With

End Sub

'#####################################
Sub moveNode1Right10(myShape As Object)

pointsArray = myShape.Nodes.Item(1).Points

currXvalue = pointsArray(1, 1)
currYvalue = pointsArray(1, 2)

MsgBox "X= " & currXvalue & Chr(13) _
& "Y= " & currYvalue

End Sub

Tecnik
05-09-2006, 08:34 AM
Hi Killian,

Thanks for the help again and the quick reply.

I'm going to have to play with this because for some reason it's not working for me :think:.

I'll let you know how I get on.

Thanks again for the help, it's much appreciated.

Regards

Nick

fumei
05-09-2006, 07:40 PM
Do lines have nodes?

Tecnik
05-10-2006, 01:12 AM
Hi Killian,

I tried the code again when I got home last night and it worked ok.
It would only work the once, which was strange, gonna have to figure out why that is.:think:

Thanks again for your help with this, it was interesting to see another way of working,
I find it useful looking through sections of code.



Gerry, not sure if this answers your question but if you run this:-
Selection.ShapeRange.Nodes.SetPosition 1, 100,100
it moves node 1, on the selected line, to position 100,100 relative to the top left of the page.

Regards

Nick

Tecnik
05-11-2006, 07:25 AM
Hi Killian,
As mentioned earlier I found that the code you'd posted would only work the once and then it wouldn't work....
Out of curiosity I tried commenting out the
If .Type = wdSelectionInlineShape Or _
.Type = wdSelectionShape Then
and
If .ShapeRange.Type = msoLine Then
and the 'End If' lines. Once I'd done this I found the script would work evry time which lead me to wonder if the '.Type' was changing after the first call and this is why it wouldn't work a second time?

In the end I trimmed the code down to this which, so far, seems to work ok. I'm not sure if this is the best way of working?
Sub moveNode()
Dim shp As Object
With Selection
Set shp = Selection.ShapeRange(1)
pointsArray = shp.Nodes.Item(1).Points
currXvalue = pointsArray(1, 1)
currYvalue = pointsArray(1, 2)
shp.Nodes.SetPosition 1, currXvalue + 10, currYvalue
End With
End Sub

Any thoughts would be appreciated.

Thanks again Killian,

Nick

Tecnik
05-11-2006, 07:44 AM
Hi Killian,
As mentioned earlier I found that the code you'd posted would only work the once and then it wouldn't work....
Out of curiosity I tried commenting out the
If .Type = wdSelectionInlineShape Or _
.Type = wdSelectionShape Then
and
If .ShapeRange.Type = msoLine Then
and the 'End If' lines. Once I'd done this I found the script would work evry time which lead me to wonder if the '.Type' was changing after the first call and this is why it wouldn't work a second time?

In the end I trimmed the code down to this which, so far, seems to work ok. I'm not sure if this is the best way of working?
Sub moveNode()
Dim shp As Object
With Selection
Set shp = Selection.ShapeRange(1)
pointsArray = shp.Nodes.Item(1).Points
currXvalue = pointsArray(1, 1)
currYvalue = pointsArray(1, 2)
shp.Nodes.SetPosition 1, currXvalue + 10, currYvalue
End With
End Sub

Any thoughts would be appreciated.

Thanks again Killian,

Nick




Further to the earlier post, I tried putting in some message boxes to see what was happening values wise and it would appear that the '.ShapeRange.Type' changes from 9 to 5 after the first execution of the script. That probably explains why the script will only work the once on a new line.

Killian
05-11-2006, 08:33 AM
Yes, it seems that moving a node changes the object from a "Line" to a "freeform", or something...

The If.. End If tests are there because without them, if the selection is not a shape with nodes, your code accessing the node will cause an error. It may take some experimentation with different shape types to see how this works...

fumei
05-11-2006, 09:52 PM
That is because lines do NOT have nodes. If you explicitly pass a node instruction to the line object Word is polite enough to say....hmmmm, OK, sure I can do that but then it is no longer a line, it is a freeform, but hey...why not?

As for:Selection.ShapeRange.Nodes.SetPosition 1, 100,100 If I run that on a selected line, I get an error stating:

"This member can only be accessed by a freeform object."