Jump to content

Word UDF _Word_DocRangeSet affecting a different range


ahha
 Share

Recommended Posts

Okay this is likely due to my not properly understanding objects.

I'm using _Word_DocRangeSet to extend a range (in this case to the end of a line).

The issue I've encountered is that extending one range seems to affect another range.

It may be that an object can't be assigned or equated.

In any event the program and test file (place in the same directory) illustrate the issue.

Test 1 - shows the documentation for _Word_DocRangeSet correctly shows how the range is extended and the assigned result is extended.  No problem here just part of my learning.

Test 2 - like Test 1 but no assignment of the result from  _Word_DocRangeSet is needed.  Again correct and my learning.

Test 3 - here is where the issue is.  After an assignment to a new object the old one seems to be affected by _Word_DocRangeSet.  This I don't understand (perhaps the assignment is really a namespace pool and points to the same structure like aliases <-- wild guess).

Test 4 - shows that using .Select can extend the range and leave the original range alone.

Any hints/pointers on what's going on appreciated.

Thanks

WordRangeTesting v1c.au3

Test for WordRangeTesting v1c.docx

Link to comment
Share on other sites

200 lines of code - that's kind of a huge reproducer script :)
Can you please strip it down to let's say 10 lines so we can concentrate on the lines causing the "problem"?

I just checked and the Word UDF does not use ByRef for the function parameters. So you only get variables set/changed when assigning the return value of a function.

BTW: Can you please add some information about the Office and AutoIt version you run?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Will check as soon as I return to my office.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

After some playing with your script I can only say: WAD - works as designed.

We create a Range object in Word by _Word_DocFind and assign it to Variable A. Then we copy variable A to variable B. So now both variables point to the same Range object. When we extend this Word Range Object only the starting and ending point properties get changed - the object is still the same. So variables A and B still point to the same Range Object with the new starting and ending Point.

You need to CREATE a new Range object as shown in my example code:

#include <MsgBoxConstants.au3>
#include <Word.au3>

Global $oWord = _Word_Create()
Global $sTestfile = "\Test for WordRangeTesting v1d.docx"
Global $oDoc = _Word_DocOpen($oWord, @ScriptDir & $sTestfile)
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "ERROR", "Error opening file = '" & @ScriptDir & $sTestfile & "'" & @CRLF & "@error = " & @error & ", @extended = " & @extended)

Global $oRange1 = _Word_DocFind($oDoc, "003")
MsgBox($MB_SYSTEMMODAL, "", "Range1 after _Word_DocFind: " & $oRange1.Characters.Count & " characters!")
$oRange1.Underline = True
MsgBox($MB_SYSTEMMODAL, "", "Range1 underlined!")

Global $oRangeTemp = $oDoc.Range($oRange1.Start, $oRange1.End); <== Create a new range object with start/end of $oRange1
MsgBox($MB_SYSTEMMODAL, "", "Range1 = RangeTemp? " & $oRange1.Isequal($oRangeTemp))
_Word_DocRangeSet($oDoc, $oRange1, Default, Default, $wdParagraph, 2) ; extend range to and including paragraph character - TRYING to leave $oRingeFind alone
MsgBox($MB_SYSTEMMODAL, "", "Range1 = RangeTemp? " & $oRange1.Isequal($oRangeTemp))
MsgBox($MB_SYSTEMMODAL, "", "Range1 " & $oRange1.Characters.Count & " characters!")
MsgBox($MB_SYSTEMMODAL, "", "RangeTemp " & $oRangeTemp.Characters.Count & " characters!")
$oRange1.Bold = True
MsgBox($MB_SYSTEMMODAL, "", "Range1 bold!")
$oRangeTemp.Italic = True
MsgBox($MB_SYSTEMMODAL, "", "RangeTemp italic!")

 

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

water,

Thanks.  Still playing with it.  Part of my confusion I believe was based on my using arrays where you can copy array $A by assignment like $B = $A.  (As explained here:  https://www.autoitscript.com/forum/topic/115345-copy-array/ )

So if I understand correctly an assignment of a variable to an object is just another pointer to the same object and as you stated earlier "So you only get variables set/changed when assigning the return value of a function. "

I was not aware of this construct:

Global $oRangeTemp = $oDoc.Range($oRange1.Start, $oRange1.End); <== Create a new range object with start/end of $oRange1

So I'm still unclear how this is a return value of a function as it appears to be an assignment.

I'll play more with it when I get back from work. 

Thanks.

Link to comment
Share on other sites

1 hour ago, ahha said:

So if I understand correctly an assignment of a variable to an object is just another pointer to the same object

Correct.

1 hour ago, ahha said:

as you stated earlier "So you only get variables set/changed when assigning the return value of a function. "

So I'm still unclear how this is a return value of a function as it appears to be an assignment.

Forget this. I was on the wrong track when analyzing the "problem".

To sum it up:
_Word_DocFind returns a range which is then assigned to a variable. When you assign this avariable to another variable you end up with two variables pointing to the same range. Modifying the range takes effect for both variables.
The only way to save the Range before you modify it is to create a new range the way i described above.

Hope I could shed some light onto the subject.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

water,

Okay I'm trying to copy with formatting and I've got something wrong.  This is not a range question so if I should start another topic let me know.

#AutoIt3Wrapper_run_debug_mode=Y    ;use this to debug in console window <--- LOOK

#include <MsgBoxConstants.au3>
#include <Word.au3>

$oWord = _Word_Create()     ;Create application object
$testfile = @ScriptDir & "\Test for WordRangeTesting v1f.docx"
$oDoc = _Word_DocOpen($oWord, $testfile, Default, Default, True)    ;put test file in same directory as script
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "ERROR", "Error opening file = '" & $testfile & "'" & @CRLF & "@error = " & @error & ", @extended = " & @extended)

$oRangeFind1 = _Word_DocFind($oDoc, "little", Default, Default, True)
$oRangeFind2 = _Word_DocFind($oDoc, "fleece", Default, Default, True)
$oRangeFind3 = _Word_DocFind($oDoc, "everywhere", Default, Default, True)

_Word_DocFindReplace($oDoc, "001", $oRangeFind1.Text)
_Word_DocFindReplace($oDoc, "002", $oRangeFind2.Text)
_Word_DocFindReplace($oDoc, "003", $oRangeFind3.Text)
Pause("Only text found and replaced.")

;now try with formatting
_Word_DocFindReplace($oDoc, "005", $oRangeFind1.FormattedText)
_Word_DocFindReplace($oDoc, "006", $oRangeFind2.FormattedText)
_Word_DocFindReplace($oDoc, "007", $oRangeFind3.FormattedText)
Pause("Text with formatting found and replaced.  Formatting NOT being picked up.  Why not?")


;----------------- functions --------------------

Func    Pause($string)
        MsgBox($MB_SYSTEMMODAL, "DEBUG", $string)
EndFunc

Thanks

Test for WordRangeTesting v1f.docx

Edited by ahha
Link to comment
Share on other sites

That's because the function only replaces text and clears the formatting before the replace is being done.
See this two lines in the UDF:

$oFind.ClearFormatting()
$oFind.Replacement.ClearFormatting()

 

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Thanks - now trying to figure it out.  I've tried copying the range to the new location using .InsertAfter and it appears to clear the formatting, so I guess I'm stuck.  Do you happen to know what operation/function can copy the formatting so that I can paste it into to a different location with the formatting maintained?

Thanks

Link to comment
Share on other sites

I would try:

$oSourceRange.Copy()
$oTargetRange.Paste()

as described here: https://msdn.microsoft.com/VBA/Word-VBA/articles/range-copy-method-word

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

water,

From another post where I was using .Copy which was shown as not reliable you suggested using .Text to get the contents (which is far superior and faster) - so I was trying to avoid .Copy.  So I found the .FormattedText and thought it would work.  Thus my question about what functions/operations might maintain formatting.   Is it possible to replace one range with another?  I can't seem to get .Replacement to work.

https://msdn.microsoft.com/en-us/vba/word-vba/articles/selection-formattedtext-property-word

https://msdn.microsoft.com/en-us/library/office/aa211953(v=office.11).aspx

 

 

Link to comment
Share on other sites

$oRangeFind1 = _Word_DocFind($oDoc, "little", Default, Default, True)
$oRangeFind2 = _Word_DocFind($oDoc, "005", Default, Default, True)
$oRangeFind2.FormattedText = $oRangeFind1.FormattedText

Untested: Should replace text and formatting of "005" with text and formatting of "little".

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

water,

I can't seem to get your .FormattedText to work although one would think it should.  The code below shows one approach of saving font properties but the problem is I don't know all the .Font properties and can't seem to find a reference that lists them all.   I next tried Duplicating the font ($oldFont = $oRangeFind3.Font.Duplicate) but assigning it does not work although it would seem that if you can save the font properties you should be able to apply them.  Any help appreciated.

#AutoIt3Wrapper_run_debug_mode=Y    ;use this to debug in console window <--- LOOK

#include <MsgBoxConstants.au3>
#include <Word.au3>

$oWord = _Word_Create()     ;Create application object
$testfile = @ScriptDir & "\Test for WordRangeTesting v1f.docx"
$oDoc = _Word_DocOpen($oWord, $testfile, Default, Default, True)    ;put test file in same directory as script
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "ERROR", "Error opening file = '" & $testfile & "'" & @CRLF & "@error = " & @error & ", @extended = " & @extended)

$oRangeFind1 = _Word_DocFind($oDoc, "everywhere", Default, Default, True)   ;everywhere is bold
$oRangeFind2 = _Word_DocFind($oDoc, "005", Default, Default, True)

;see https://msdn.microsoft.com/en-us/vba/word-vba/articles/font-object-word
;https://msdn.microsoft.com/VBA/Word-VBA/articles/object-model-word-vba-reference

;save
$oldFontName = $oRangeFind1.Font.Name
$oldFontSize = $oRangeFind1.Font.Size
$oldFontBold = $oRangeFind1.Font.Bold

;operation
$oRangeFind2.Text = $oRangeFind1.Text

;restore
$oRangeFind2.Font.Name = $oldFontName
$oRangeFind2.Font.Size = $oldFontSize
$oRangeFind2.Font.Bold = $oldFontBold

Pause("save/restore")

;try another approach

$oRangeFind3= _Word_DocFind($oDoc, "little", Default, Default, True)    ;little is underlined
$oRangeFind4 = _Word_DocFind($oDoc, "007", Default, Default, True)

;from https://stackoverflow.com/questions/1739729/word-2007-vba-to-insert-text
$oldFont = $oRangeFind3.Font.Duplicate      ;save the format/font of the source

$oRangeFind4.Text = $oRangeFind3.Text

$oRangeFind4.Font = $oldFont    ;does not work! is there a way to apply the saved font??
Pause("$oRangeFind2.Font = $oldFont")

;----------------- functions --------------------

Func    Pause($string)
        MsgBox($MB_SYSTEMMODAL, "DEBUG", $string)
EndFunc

 

Test for WordRangeTesting v1f.docx

Edited by ahha
Typo
Link to comment
Share on other sites

Can't test at the moment.
But maybe the PasteAndFormat method (https://msdn.microsoft.com/de-de/vba/word-vba/articles/range-pasteandformat-method-word does what you are looking for.
As type I suggest to use wdFormatOriginalFormatting (https://msdn.microsoft.com/de-de/vba/word-vba/articles/wdrecoverytype-enumeration-word)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

Water,

Tried   $oRangeFind4.PasteAndFormat.wdFormatOriginalFormatting

and get ==> The requested action with this object has failed.:

So my assumption is my expression is wrong.  Tried several others and nothing works so far.  Will keep trying.

 

Link to comment
Share on other sites

Should be:

Global $wdFormatOriginalFormatting = 16 ; Preserves original formatting of the pasted material.
$oRangeFind4.PasteAndFormat($wdFormatOriginalFormatting)

wdFormatOriginalFormatting is a parameter to the PasteAndFormat method.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

water,

The .PasteAndFormat uses the .Copy contents correct?  And .Copy doesn't it use the clipboard?  I ask because I was trying to do it without using the clipboard (which is not consistent). 

Is there any way of applying a stored font/format to a range?

$oldFont = $oRangeFind3.Font.Duplicate      ;save the format/font of the source

$oRangeFind4.Text = $oRangeFind3.Text

$oRangeFind4.Font = $oldFont    ;does not work! is there a way to apply the saved font??
Link to comment
Share on other sites

water,

Does .Copy return any error codes?

From here: https://msdn.microsoft.com/VBA/Word-VBA/articles/range-copy-method-word

It does not show any.  I ask because the ClipPut and ClipGet do return error codes so one can check that they worked properly.  On the other hand I'm trying to make sure .Copy worked or is .Copy guaranteed to work?

Thanks

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...