Subscribe to this thread
Home - General / All posts - Copy and Paste Error
mghasemi
94 post(s)
#22-Jun-16 23:56

Hello,

I have a long script which I am loading multiple excel files and create several drawings from the input tables.

I built one template drawing and copy it several times:

drwg.copy false

Document.paste

It stopped in line of "Document.paste"

so I added a delay between copy and paste.

Now randomly, the program stops in "drwg.copy false" line. For example stops in 3rd copy and if I re-execute it pass that one and stops in 7th one where I use copy.

Why does it should give error for Copy command?

COuld anyone please help me how to fix this?

tjhb
10,094 post(s)
#23-Jun-16 00:11

Does your script use user interface (UI) scripting?

There have been several recent forum threads on timing issues with UI scripting, including some directly addressing copy and paste.

I'll try to find exact links so you don't have to search.

tjhb
10,094 post(s)
#23-Jun-16 00:16

Have a look at these threads (there are others):

http://www.georeference.org/forum/t130788.3

http://www.georeference.org/forum/t130720.28

But for more help, post your script, and preferably some sample data it can use.

mghasemi
94 post(s)
#23-Jun-16 00:26

Yes, I use UI throughout the script.

mghasemi
94 post(s)
#23-Jun-16 00:31

Thanks for the link.

I did several search throughout the posts and specifically I read these two.

I added the delay after copy

drwg.copy

delay 2

document.paste

However, now the error shifted from Paste to copy line.

It stops in line where I have copy statement.

If I run it again it stops in another copy.

mghasemi
94 post(s)
#23-Jun-16 00:36

This is part of the script:

set Tbl=Document.ComponentSet("WellLocations_Table")

If Document.ComponentSet.ItemByName(Tbl.Name & " 2")<> -1 Then ' It does exist

Document.ComponentSet.Remove(Tbl.Name & " 2")

End If

Tbl.Copy False

Delay 2.5, True

Set UI = Application.UserInterface

UI.InvokeCommand "ViewProjectPasteAsDrawing", "Pane:Project"

Do ' Nothing

Loop Until ui.DisplaysModalDialog

Set dlg = ui.ModalDialog

With Dlg.ControlSet

.Item("ComboBoxX").Text = "X"

.Item("ComboBoxY").Text = "Y"

.Item("CheckBoxLatitudeLongitudeCoordinates").Checked = False

.Item("ButtonOK").Push

End With

The error message says : "Line 401" which is the line for Tb.copy false

I reexcuted the script (without any change) and now it stopped in line 571 (line says: Boxdrwg.copy)

Set Boxdrwg=Document.Componentset("BoxLocations_Table_Boxes")

'Make PVInj Drawing

If Document.ComponentSet.ItemByName(BoxDrwg.name & " 2")<> -1 Then ' It does exist

Document.ComponentSet.Remove(BoxDrwg.name & " 2")

End If

Boxdrwg.copy false

Delay 2.5, True

Document.Paste

steveFitz

340 post(s)
#23-Jun-16 06:01

Who can resist a kitty with big pleading eyes like that?

So I tried the following and it works for me. Let me know if this works for you using a single, simple table called 'Table'

'vbscript

Sub Main

 Application.MessageBox "Hello, World!""Script"

 set Tbl=Document.ComponentSet("Table")

 If Document.ComponentSet.ItemByName(Tbl.Name & " 2")<> -1 Then ' It does exist

 Document.ComponentSet.Remove(Tbl.Name & " 2")

 End If

 Tbl.Copy False

 Delay 2.5, true

 Set UI = Application.UserInterface

 UI.InvokeCommand "ViewProjectPasteAsDrawing""Pane:Project"

 Do 

 ' Nothing

 Loop Until ui.DisplaysModalDialog

 Set dlg = ui.ModalDialog

 With Dlg.ControlSet

 .Item("ComboBoxX").Text = "X"

 .Item("ComboBoxY").Text = "Y"

 .Item("CheckBoxLatitudeLongitudeCoordinates").Checked = False

 .Item("ButtonOK").Push

 End With

End Sub

Private Sub Delay(s, doLog)

 ' The Shell.Sleep method is not available within the Manifold context

 ' so we use an "active" loop instead (occupies a core)

 Dim i

 Dim start

 For i = 1 To s

 start = Now

 Do ' Nothing

 Loop Until DateDiff("s", start, Now) >= 1

 ' More robust than Timer function

 ' if operation spans midnight

 If doLog Then Application.History.Log "."True

 Next

 If doLog Then Application.History.Log vbCrLf, True

End Sub

firsttube


1,439 post(s)
#23-Jun-16 14:46

I've experienced the same problem periodically and a computer restart usually fixes it. Not ideal, but it has worked.


"The blessing in life is finding the torture you are comfortable with." - Jerry Seinfeld, 6/26/2013

mghasemi
94 post(s)
#23-Jun-16 15:23

Thank you "firsttube"

I will try rebooting the machine and see if it helps.

mghasemi
94 post(s)
#23-Jun-16 15:22

Steve,

this is the same exact code.

I have one table to copy and more than 20 times copy of one template drawing.

So the script stops in line where I call copy. and this is random, i.e. one time in one line and next time I run in another line.

firsttube


1,439 post(s)
#23-Jun-16 16:53

Another way to "copy/paste" would be to use SQL...


"The blessing in life is finding the torture you are comfortable with." - Jerry Seinfeld, 6/26/2013

tjhb
10,094 post(s)
#23-Jun-16 21:17

It really would be good if you could post the actual script you are running. Not a part of it, the actual whole script. An efficient way to do that is to export the script to a .txt file and attach it to a post.

Another thing that would help is to post the exact text of the error messages you get, or screenshots.

I think I can see what may be going on: clipboard transfer code is being (re)invoked by .Copy before the code manipulating it with .PasteAs has had time to finish. Setting the clipboard contents requires synchronous operation. So to Copy and Paste repeatedly, you must wait both after the Copy (before Paste) and after the Paste (before the next Copy).

It would be much tidier though to upgrade this to a .NET script and use some better techniques than are available in VBScript. Are you happy to install IronPython?

mghasemi
94 post(s)
#23-Jun-16 23:31

tjhb,

thanks for your response.

I don't know. Net and so it would not be easy for me to convert.

I attached the script.

It does not show any specific message. It just shows a warning message with line number, once I click OK, it takes to that line which is highlighted.

I tried that as well, having a delay before each copy as long as 5 seconds. this did not fix.

I have used the same script several times last year and there was no error. I receievd this error only recently.

Attachments:
script.txt

tjhb
10,094 post(s)
#24-Jun-16 00:09

Thanks for the code and further notes, I'll take a closer look.

[Added.] The code is corrupted (by Office tags?). Could you just export your actual working code from Manifold to a text file, make sure you can read it in (say) Notepad, and attach that file here?

tjhb
10,094 post(s)
#24-Jun-16 01:59

Not corrupted, just not in Manifold standard format--I think only CR, not CRLF, at line ends--easily fixed. No need to re-post, thanks.

tjhb
10,094 post(s)
#24-Jun-16 03:33

The script has become a bit unwieldy--especially since it's VBScript.

There's nothing really wrong with it but it would be much better to break things down much more. There aren't all that many options for doing that with VBScript--it is not really your friend when you have such a long procedure--but there are some.

One example: there are 20 instances of .Copy and 20 instances of .Paste. These sections of code could all be moved to one or two standard functions. Getting one instance failsafe would get them all failsafe.

A simple thing that's (sort of) wrong throughout is that although you are waiting for a modal dialog, you aren't explicitly waiting for the right modal dialog, i.e. a dialog with the expected caption. In practice it's often essential to do both, i.e. wait twice, to prevent random timing errors. I've written a fairly bulletproof function to do that, which you can use each time instead of a simple in-line loop. It has a timeout.

Sub WaitForUIDialog(caption, timeout)

    ' Wait for a modal dialog with the specified caption to show

    ' subject to an overall timeout in seconds 

    ' (-> log and throw error)

    Dim ui

    Dim start

    Set ui = Application.UserInterface

    start = Now

    ' Wait for some modal dialog to show

    Do

        If DateDiff("s", start, Now) >= timeout Then

            Application.History.Log "Timeout waiting for modal dialog (" _

                & CStr(DateDiff("s", start, Now)) & " sec)" & vbCrLf, _

                True

            Err.Raise 17 ' Can't perform requested operation

            'Exit Do ' not required

        End If

    Loop Until ui.DisplaysModalDialog 

    ' Wait for the current modal dialog to show the expected caption

    Set dlg = ui.ModalDialog

    Do

        If DateDiff("s", start, Now) >= timeout Then

            Application.History.Log "Timeout waiting for " & Chr(34) & caption & Chr(34) & " dialog (" _

                & CStr(DateDiff("s", start, Now)) & " sec)" & vbCrLf, _

                True

            Err.Raise 17 ' Can't perform requested operation

            'Exit Do ' not required

        End If

    Loop Until ui.ModalDialog.Caption = caption

End Sub

But obviosuly there is a lot more to look at here.

tjhb
10,094 post(s)
#24-Jun-16 04:24

Oops there's a redundancy in the code above. Either remove

Set dlg = ui.ModalDialog

or change

Loop Until ui.ModalDialog.Caption = caption

near the end to

Loop Until dlg.Caption = caption

That's probably faster, though since we're just waiting that might be academic.

We also need a

Dim dlg

statement up top (at least if Option Explcit is used).

Sorry about that.

Sub WaitForUIDialog(caption, timeout)

    ' Wait for a modal dialog with the specified caption to show

    ' subject to an overall timeout in seconds 

    ' (-> log and throw error)

    Dim ui

    Dim start

    Dim dlg

    Set ui = Application.UserInterface

    start = Now

    ' Wait for some modal dialog to show

    Do

        If DateDiff("s", start, Now) >= timeout Then

            Application.History.Log "Timeout waiting for a modal dialog (" _

                & CStr(DateDiff("s", start, Now)) & " sec)" & vbCrLf, _

                True

            Err.Raise 17 ' Can't perform requested operation

            'Exit Do ' not required

        End If

    Loop Until ui.DisplaysModalDialog 

    ' Wait for the current modal dialog to show the expected caption

    Set dlg = ui.ModalDialog

    Do

        If DateDiff("s", start, Now) >= timeout Then

            Application.History.Log "Timeout waiting for " & Chr(34) & caption & Chr(34) & " dialog (" _

                & CStr(DateDiff("s", start, Now)) & " sec)" & vbCrLf, _

                True

            Err.Raise 17 ' Can't perform requested operation

            'Exit Do ' not required

        End If

    Loop Until dlg.Caption = caption

End Sub

tjhb
10,094 post(s)
#23-Jun-16 23:20

Even without a .NET upgrade, the script can be substantially upgraded to make looping over multiple components both easier and more reliable.

steveFitz

340 post(s)
#24-Jun-16 00:27

mghasemi,

this is the same exact code.

My code has a Sub Main and End Sub so it runs independent of any other code. It also has a function missing from your code (who knows what is actually in your function (it also has a simple table with 1 or 2 lines).

I find its good to try to isolate any problems to their simplest form for basic trouble shooting. This make it easy to replicate an analyse for yourself and others.

If it doesn't work on your computer then we can now say that there is something different between your set up and mine. Its a start.

Manifold User Community Use Agreement Copyright (C) 2007-2021 Manifold Software Limited. All rights reserved.