Consulting

Results 1 to 16 of 16

Thread: Code works when stepping but not when running

  1. #1
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location

    Code works when stepping but not when running

    Up to a point my macro works OK. It creates a table & populates it, 2 rows at a time, until it reaches the bottom of the page. The 1st cell in each 'set' contains an image. The 2nd contains information about the image. (Starting with the file name.) When I reach the end of the row (by counting the images inserted, there are 6 images/row) I 'tab' to create the next row, then I 'tab' 6 more times to create a second row. The problem:

    My AddImage routine moves up 1 line (to the 'image' row), inserts the image, then moves down 1 line to type the filename & other info, then moves right to the next column. This works fine when stepping through the code, even when the new rows are on a new page. When I'm running it for production though the macro doesn't move down before typing the filename & other info. It adds that to the same cell as the image & that messes up everything that follows on the new page.

    I don't understand why it works correctly in debug mode but not in production. I'll post the code if necessary (I'd like to remove the unrelated stuff first, like how it calculates the info that it'll type) but in essence the question isn't with how to do what I want to do but why it does it fine when debugging but not when running straight through. Thanks.

  2. #2
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Impossible to know without you posting code. Most of the time, the difference between running code vs. stepping through in debug.mode has something to do with the way it's programmed. Rarely, it might be some kind of word bug which you then have to program around.

    But based on your general description of 'tabbing' to crete a second row means you're working with something which started as a recorded macro (for example, you can use .Rows.Add to create a row properly).

    I suspect you'll learn a lot by posting the code you're using an adopting whatever new code is recommended... but first step is on you.

    Please remember cross-posting etiquette.
    _______________________________________________
    Please don't cross-post without providing links to your cross-posts. We answer questions for free. Please don't waste the time of the people helping you.
    For cross-posting etiquette, please read: http://www.excelguru.ca/content.php?184

    - Frosty

  3. #3
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location
    Cross-posting? IIRC that's posting the same question in multiple forums. This is the only forum I've ever deliberately posted any question in. Can you explain how I violated cross-posting etiquette? If I did that I certainly didn't mean to.

    I agree that I could use Rows.Add to create a row-but I don't see why that's any more proper than the way I'm doing it. And I do have a reason (besides starting with a recorded macro). It's simpler (IMO)-I use the same code that moves me from cell to cell to add the row. I could add 2 rows at once using Rows.Add but then I'd need to check whether I'm at the end of a row before moving to the next cell. I'm still working on creating a simplified macro I can post. I'll post the simplified AddImage function below but until I finish simplifying the entire macro I can't test it. The code I removed (calculating the additional info) shouldn't change the behavior-but I can't be sure until I test this. If I knew for sure what was causing the behavior I wouldn't need to ask the question, right?

    So, the simplified AddImage function is:
    Function AddImage(ByVal ImagePath As String, ByVal ImageFile As String) As Boolean
    Dim OtherInfo as String
        Selection.MoveUp Unit:=wdLine, Count:=1
        Selection.InlineShapes.AddPicture FileName:=ImagePath & ImageFile
        'error checking code that sets AddImage = False & exits if there's a problem
    OtherInfo = "This & That"
        Selection.MoveDown Unit:=wdLine, Count:=1
        Selection.TypeText Text:=ImageFile
        Selection.TypeParagraph
        Selection.TypeText Text:=OtherInfo
        Selection.MoveRight Unit:=wdCell
        AddImage = True
    End Function
    Thanks.
    Hmm. The <VBA></VBA> tags don't seem to work. Hopefully you can make sense out of the code. Thanks.

    I've been thinking. Maybe I should start over, seeking help to set this up the way I'd like it to be set up. Right now I let the cells autosize to fit the contents because I can't figure out how to resize the contents to fit the cell. For the images that's not a big deal-if a folder contains incorrectly sized images the document won't be right, the users will report that, and I'll go in & resize the images in that folder. But, there's the possibility that the other info will expand beyond 4 lines thus increasing the height of the info row-which might push other rows to the next page so currently I need to check for the end of page.

    If I could resize contents to fit a fixed-size cell then I could use a standard number of cells/page. I might end up with a messier document (a separate table on each page, for example) but I can live with that-the documents might get regenerated but should not be edited. So, should I start over? Thanks.
    Last edited by calvin-c; 02-13-2014 at 03:12 PM. Reason: Alternative approach

  4. #4
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    My first comment wasn't because you cross-posted, but because as a 1 post-count new user, that's generally the scenario where someone *might* be cross-posting. No worries.

    As for your other question... hrm. You might want to post enough posts (I think it's 5) in order to post a sample document with a table like you're inserting the picture and picture data in. Doesn't need to be "real" pictures, but the format can be important.

    When you have code which makes use of the Selection, it is very breakable if your selection isn't in the "right" spot. How do you know your selection is in the right location when it runs? If I ran the above code on a blank new document, it would fail at the very first line (Selection.MoveUp wdLine, 1), because the Selection is already *at* the first line of the document.

    But it wouldn't fail when I'm stepping through, because I'd probably have my cursor somewhere else in the document.

    I suspect you'll end up needing/wanting to understand working with range objects to make your code less breakable, but greg maxey's website also has something which addresses something like this, I believe (although I don't remember the actual one).

    http://gregmaxey.mvps.org/word_tips.html is the generic link, and I think this link might be helpful...

    http://gregmaxey.mvps.org/word_tip_p...h_content.html

  5. #5
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    It is not VBA (open and close tags) anymore; it is code (open and close) tags.

  6. #6
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location
    Thanks for clearing up the cross-posting, Frosty. & thanks for the tag clarification, fumei. I'll check GregMaxey's site.

    I like Range objects but don't have a problem with using Selection. As long as the program isn't interactive (and works as tested) I know where the cursor is. I'm not sure whether your comment that Selection is breakable refers to the problem I'm having (which, as far as I can see isn't related to cursor position unless Selection.Move acts differently during debug than when running) or is simply a general observation about it. I don't have a lot of experience with VBA but I do with VB (from version 6 to 2005 .Net) so I'll agree with your general observation-particularly when other programmers start making modifications. I retired 3 years ago so all my programming is for myself now. If I screw it up because I used Selection I think I know who to blame.

    Thanks.

  7. #7
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Unfortunately, the advice has to be general until you can give demo code which breaks when running on a sample doc but doesn't in debug mode.

    There are a host of differences implied in debug mode vs running the code-- the addin being open, word being launched, the document being the correct document, the ribbon fully loaded. Etc etc.

    There are no general reasons for what your generic description isn't working. But obviously it isn't. You may be encountering a bug in Word's selection object (unlikely, as it is probably the most tested object in Word), or you may be switching documents without knowing it, and so the selection you have when debugging is the same as you expect, but it isn't when running it.

    What's actually happening when it doesn't work?

  8. #8
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    calvin, you need to post your full code. There is not much anyone can do without being able to test it ourselves. I do suspect that Jason is correct in that it most likely has something to do with using Selection. But nothing can be confirmed without seeing the full code.

  9. #9
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location
    Seems like a lot to post when the problem is only in a small function but... I would like to figure this out even if I end up starting over. Here's the full code & I'm attaching a zipped folder with test document & images.
    Sub NewCatalog()
    '
    'Create a new catalog document
    '
        'location of header templates, changes with different users & versions of Windows or Office
        Dim BuildingBlocks As String
        BuildingBlocks = "C:\Users\Calvin\AppData\Roaming\Microsoft\Document Building Blocks\1033\Building Blocks.dotx"
        
        Dim Topic As String
        Topic = "Animals"
        
        'create new document from Normal template so it doesn't contain this macro
        Dim TopicDoc As Document
        Set TopicDoc = Documents.Add(Template:="Normal", NewTemplate:=False, DocumentType:=0)
        With Selection.PageSetup
            .TopMargin = InchesToPoints(0.5)
            .BottomMargin = InchesToPoints(0.5)
            .LeftMargin = InchesToPoints(1)
            .RightMargin = InchesToPoints(0.5)
            .HeaderDistance = InchesToPoints(0.5)
            .PageWidth = InchesToPoints(8.5)
            .PageHeight = InchesToPoints(11)
            .SectionStart = wdSectionNewPage
            .OddAndEvenPagesHeaderFooter = False
            .DifferentFirstPageHeaderFooter = False
        End With
        'attach BuildingBlocks template
        ActiveDocument.AttachedTemplate = BuildingBlocks
        'add 1st header
        ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
        FirstHeader (Topic)
        ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
        CreateTable1
        
        Dim ImageFile As String
        Dim ImagePath As String
        Dim ImageCount As Integer
        Dim PageNum As Integer
        Dim OldPage As Integer
        Dim TestCount As Integer
        Dim Result As Boolean
        
        'need path to insert image but filename must be separate for info
        ImagePath = "C:\Test\" & Topic & "\"
        ImageFile = Dir(ImagePath & "*.*")
        'error check in case Topic folder is empty
        If ImageFile = "" Then
            MsgBox (Topic & " contains no files")
            Exit Sub
        End If
        
        ImageCount = 1
        PageNum = 1
        TestCount = 1
        
        Do Until ImageFile = "Done"
            'add images & file names from folder
            'AddImage advances to next cell which, if at end of row, adds next row
            'but need to add 2 rows so use ImageCount to find end of row (6 images/row)
            Result = AddImage(ImagePath, ImageFile, TestCount)
            If Result = False Then
                ImageFile = "Done"
            End If
                
            If ImageCount = 6 Then
                'easiest way to add another row is tab thru the current row
                Selection.MoveRight Unit:=wdCell, Count:=6
                ImageCount = 1
                'ImageFile = "Done"
            Else
                ImageCount = ImageCount + 1
            End If
            TestCount = TestCount + 1
            
            If ImageFile = "Done" Then
                Exit Do
            End If
            ImageFile = Dir
            If ImageFile = "" Then
                ImageFile = "Done"
            End If
        Loop
    'save/close new document when all images have been added
    End Sub
    
    Sub FirstHeader(ByVal Topic As String)
        ActiveDocument.AttachedTemplate.BuildingBlockEntries( _
            " Blank (Three Columns)").Insert Where:=Selection.Range, RichText:=True
        Selection.HomeKey Unit:=wdLine
        Selection.Delete Unit:=wdCharacter, Count:=1
        Selection.Font.Name = "Broadway BT"
        Selection.Font.Size = 14
        Selection.TypeText Text:="Catalog Name"
        Selection.MoveRight Unit:=wdCharacter, Count:=1
        Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
        Selection.Delete Unit:=wdCharacter, Count:=1
        Selection.Font.Name = "AR JULIAN"
        Selection.Font.Size = 14
        Selection.TypeText Text:=Topic
        Selection.MoveRight Unit:=wdCharacter, Count:=1
        Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
        Selection.Delete Unit:=wdCharacter, Count:=1
        Selection.Font.Name = "AR JULIAN"
        Selection.Font.Size = 14
        Selection.TypeText Text:="Page "
        ActiveDocument.AttachedTemplate.BuildingBlockEntries("Plain Number"). _
            Insert Where:=Selection.Range, RichText:=True
        Selection.TypeParagraph
        Selection.Font.Name = "Calibri"
        Selection.Font.Size = 11
        Selection.TypeText Text:="Note"
    End Sub
    
    Private Sub CreateTable1()
        ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=2, NumColumns:= _
            6, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
            wdAutoFitFixed
        'start w/ cursor in bottom row so AddImage will work
        Selection.MoveDown Unit:=wdLine, Count:=1
    End Sub
    
    Function AddImage(ByVal ImagePath As String, ByVal ImageFile As String, ByVal TestCount As Integer) As Boolean
    
        Dim OtherInfo As String
        Selection.MoveUp Unit:=wdLine, Count:=1
        Selection.InlineShapes.AddPicture FileName:=ImagePath & ImageFile
        'error checking code that sets AddImage = False & exits if there's a problem
        'Stopping after inserting 1st image on new page (image 37), then continuing works
        'Stopping after inserting image 38 (or simply running without stopping) messes up 2nd page
        Debug.Assert TestCount < 38
        
        OtherInfo = "This & That"
        Selection.MoveDown Unit:=wdLine, Count:=1
        Selection.Font.Name = "Arial Narrow"
        Selection.Font.Size = 10
        Selection.TypeText Text:=ImageFile
        Selection.TypeParagraph
        Selection.TypeText Text:=OtherInfo
        Selection.MoveRight Unit:=wdCell
        AddImage = True
    End Function
    Attached Files Attached Files

  10. #10
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location
    Per comments in the AddImage function, running Debug.Assert TestCount < 37 works fine even when you Continue immediately after the Debug pauses execution. Running Debug.Assert TestCount < 38 (which logically should give the same results) causes a problem. What difference does pausing the execution (and doing nothing else) make?

  11. #11
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Well, the problem isn't "in" the small function, the problem is likely to do with where the selection is when stepping through vs. running it.

    So seeing the context of the code and what you intend to happen is critical. There's nothing wrong with your function. I wouldn't write it that way, but so what? Like any function, it depends on other things though, and in this case, I suspect the location of the selection is causing the failure.

    Can you describe how it fails too? Where is your cursor left?

  12. #12
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location
    Where the cursor is left-at what point? Technically the program doesn't fail, it just doesn't produce the results I want. When I use Debug.Assert TestCount < 37 (and switch to the document to check cursor position) the cursor is in the same cell as & immediately following the just-inserted image. The next statement, Selection.MoveDown, correctly moves the cursor to the cell immediately below the image. This occurs whether I step through that statement or simply Continue from the Debug.Assert statement.

    When I use Debug.Assert TestCount < 38 the cursor is also immediately following the just-inserted image but that image has been inserted a row higher than the preceding one (because Selection.MoveDown didn't move the cursor to the cell below image 37). I've attached the output from the incorrect processing. Thanks.
    Attached Files Attached Files

  13. #13
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location
    Unfortunately posting a document doesn't show the cursor position. I'll try to find something that does but I did put Debug.Assert TestCount < 37 immediately before Selection.MoveDown & the cursor was immediately after the just-inserted image. I then moved the Debug.Assert statement to immediately following Selection.MoveDown-and the cursor position hadn't changed. To me that indicates a problem with the Selection.MoveDown statement. I'm open to the possibility of it being something else but can't, by myself, imagine what that 'something else' could be. I've definitely narrowed down the problem to a single statement that works when execution pauses immediately before it but fails (without producing an error message) when execution runs through it-but only on a new page. I'd like to figure out why but experience says that 'why' is often unanswerable. Is there a different way to move the Selection to the next cell down?

  14. #14
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    I haven't checked out the code yet, as I'm posting from my phone. But here are a couple of ideas:
    1. DoEvents
    2. Selection.Range.Select
    3. Application.ScreenRefresh
    4. Making use of a range object instead, and traversing your table that way
    5. Trigger a manual re pagination of the document (can't remember the method off the top of my head)

    you're right, it sounds like it might have to do with Selection.MoveDown in a specific circumstance (like being at the bottom of a page?)

    in that case, the only answer is to try and "jiggle the handle", programmatically (like forcing word to update itself in some fashion) or approach from a different way (like using ranges).

    You our already know which way I would suggest, but try the other stuff first and if they don't work, then time to work with ranges. Incidentally, .MoveDown is the one thing which doesn't have an analog on the range object, but you can easily use row and cell objects (and the cells collection on a row object) to navigate around a uniform table (I.e., no merged cells anywhere)

  15. #15
    VBAX Regular
    Joined
    Feb 2014
    Posts
    12
    Location
    Application.ScreenRefresh works so I'll mark this Solved. Thanks. I still might rewrite this after I understand what Greg Maxey is doing but at least I'm past the current problem. I do wonder what causes it. Given the solution I suspect it's that Word (or Windows) manages the cursor position on a cached copy (possibly the screen memory on the video card) and it needs time to refresh the cache when something changes (like a row moving to a new page because an image is inserted). That would explain why even a slight pause would also work-which means DoEvents would probably work too but I think I prefer Application.ScreenRefresh as that makes it clear why it needs the 'pause'. Thanks.

  16. #16
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Yes, that's the other issue with using Selection. If you're doing a lot of operations, then you'll occasionally need to allow the entire application time to catch up. My guess is that Selection in this case is trying to stay on the same page when doing the .MoveDown method. I wonder if it would also work to operate in Normal view rather than Print View (or Page Layout view, depending on the version of Word).

    Since normal view (where you don't see the page borders) overall uses less resources to display the document, your code using Selection would probably run faster and also not encounter the same issue with .MoveDown at the bottom of a "page"

Posting Permissions

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