Need help placing table at beginning of page - vb.net

I am placing tables into a Word document. The number of rows in a table may vary but the row height is fixed so I know the maximum number of rows that can fit on a single page. When I reach that max number, I want to add a new page to the document and then insert a new table on it. Sounds simple but I'm running into all sorts of weird results.
Result #1: I have tried using both "Selection.InsertNewPage" and "Selection.InsertBreak(wdPageBreak)". When I do this, 2 pages are added instead of 1.
NumberOfPages = SectionObject.Range.Information(wdNumberOfPagesInDocument)
TableLocation = TableObject.Range 'get the range object of the current table
TableLocation.Collapse(WdCollapseDirection.wdCollapseEnd) 'go to end of table
TableLocation.Select()
WordDocument.Application.Selection.InsertBreak(WdBreakType.wdPageBreak) 'adds 2 pages instead of 1
NumberOfPagesNew = SectionObject.Range.Information(wdNumberOfPagesInDocument)
To try to make this work I wrote this code (it doesn't work)
If NumberOfPagesNew > NumberOfPages + 1 Then
TableLocation = WordDocument.Range.GoTo(wdGoToPage, wdGoToAbsolute, NumberOfPagesNew) 'go to last page of doc
TableLocation.Delete() 'delete that page
TableLocation = WordDocument.Range.GoTo(wdGoToPage, wdGoToAbsolute, NumberOfPagesNew - 1) 'go to new last page
TableLocation.Collapse(WdCollapseDirection.wdCollapseStart) 'move cursor to start of page
End If
'I add a new table using this code
TableObject = WordDocument.Tables.Add(TableLocation, NumberOfRowsNeeded - 1, 5)
But instead of placing my table on the last page, another page gets added and my table is placed on it. The end result is a page with a table, a blank page, and then another page with a table.
Result #2: Another thing I tried was moving my cursor to the end of the table, adding a line break and then placing my table after that. This got around my problem of adding 2 pages instead of 1. However, it adds 2 lines onto the new page instead of 1 which throws off my row counting code. Below is the code I used.
TableLocation = TableObject.Range 'get range object of current table
TableLocation.Collapse(wdCollapseEnd) 'go to end of table
TableLocation.Select()
WordDocument.Application.Selection.InsertBreak(wdLineBreak) 'should add 1 line
TableLocation = WordDocument.Application.Selection.GoToNext(wdGoToLine)
TableLocation.Collapse(WdCollapseDirection.wdCollapseStart)
'I add my next table using this code.
TableObject = WordDocument.Tables.Add(TableLocation, NumberOfRowsNeeded - 1, 5)
This code places my table one line lower than it should.
I don't do a lot of Word coding and I know very little about the intricacies of the selection object so I am sure that is where my problem lies. If someone could show me a good way of accomplishing what I want to do, I would appreciate it.
Thanks in advance,
Darren

Try the following code. Make sure that the number of rows of the table allows it to fit on one page. If this does not work, try with one fewer row in the table, Word might need some extra spaces before / after the table depending on the active format.
Selection.EndKey Unit:=wdStory
ActiveDocument.Tables.Add Selection.Range, 5, 5
Selection.EndKey Unit:=wdStory
Selection.InsertBreak WdBreakType.wdPageBreak
Selection.EndKey Unit:=wdStory
ActiveDocument.Tables.Add Selection.Range, 5, 5
' ...
Of course, this is just to show you an approach that will work and avoids the difficulties that you experienced. You need to adapt the code to your specific task.

Related

Need Word VBA code to move cursor to end of first column in two-column page layout

I have a Word VB macro that automatically inserts a Visio drawing in a two-column layout. The code works well, but I would like to further automate the process. To do so, I am looking specifically for code that will move the cursor to the end of the first column of the selected page. This column typically does not already have a column break, so my solution can't involve searching for column breaks. And I believe I already have code that selects the current page, just not the end of the first column on that page.
I am able to move the cursor to the end of the page programmatically, and I am able to move the cursor to the top of the page programmatically. I just can't get the cursor to move to the end of the first column of text. All of the online examples I've found so far focus on moving to the end of a column in a table, but not to the end of a column of text in a two-column layout.
10/15/2019: Here's an example page as requested by #cindym
[SamplePage][1]
The document may be several pages long. My current macro works well and meets company requirements for this kind of document, but it requires the user to place the cursor where they want the two-column graphic inserted. I want to make the process more automated (check "top" or "bottom" in an existing userform and have the macro place the two-column figure accordingly on the current page).
Again, I am able programmatically move the cursor to the top or bottom of the page just fine, I just can't get the cursor to the end of the first column (the left-hand column on the two-column page). Our code inserts continuous section breaks and works well if it can insert the first of those breaks at the end of the left-hand column of text.
Based in part on CindyM's suggestion, I tried the following for a two-column Visio diagram at the bottom of the current page, but things go wrong after the third line of code. Other than this initial VBA-driven cursor placement problem, the rest of my code works fine (selects the Visio, inserts continuous breaks, inserts a caption for the figure, etc.). Hope this helps clarify. Thanks again!
`ActiveDocument.Bookmarks("\Page") `Select selects current page`
Selection.GoToNext (wdGoToPage) `cursor at top of page 2`
Selection.MoveEnd wdCharacter, -1 `cursor now at end of target page`
Selection.MoveRight Unit:=wdItem `cursor now in headline, top of page :(`
Selection.MoveRight Unit:=wdItem
[1]: https://i.stack.imgur.com/OR7BF.png
As no code was included in the question as a starting point, the following uses GoTo to move to a specific page. The assumption is that this position is not a newspaper column. Then the equivalent of pressing Alt+Down Arrow twice in the UI to move to the next TextColumn (newspaper column) is performed, which would be the beginning of the next column after the first. The selection is then moved back one character, to put it at the end of the column.
If the top of the page is a newspaper column and the code should move to the end of that column, then remove one of the Selection.MoveRight Unit:=wdItem lines.
Sub MoveToEndOfNextNewspaperColumn()
Dim goToPageNr As String
goToPageNr = "1"
Selection.GoTo What:=wdGoToPage, Which:=wdGoToNext, Name:=goToPageNr
Selection.MoveRight Unit:=wdItem
Selection.MoveRight Unit:=wdItem
Selection.MoveEnd Unit:=wdCharacter, Count:=-1
End Sub

Move image without copy/paste

Right now I have a Word macro that moves an image in front of specific text by copying and pasting it to that location. This works pretty well, but it is costly. If I have 1,000s of images in my word doc it could take 30 minutes to run the macro.
There has to be a better way right?
Can I move the image anchor without copy/pasting the entire image?
My end goal is to take text + an image that is aligned in a table (text left, image right), break it out of the table, but maintain that left/right nature.
Specifically, I am looking for images in tables (row 1 column 2) and want to move them to the beginning of the text in that same table (1st column, 1st row). Here is a snippet:
For Each shape In innerTable.Cell(1, 2).Range.InlineShapes
If shape.Type = wdInlineShapePicture Then
shape.Select
Selection.Cut
innerTable.Range.Paragraphs(1).Range.Characters(1).Paste
'Do it only for the 1st image found:
Exit For
End If
Next
Note, I am leaving out some safety checks for simplicity sake (this assumes I already have found a table of valid size, etc.
It is only possible to move a Shape if the target is on the same page. In that case, a Shape can be moved by changing its Top and Left properties. Unfortunately (extremely), there is no way to move an image by changing the anchor point. So the only way to move an image to another page (or story) is using copy/paste.
If an InlineShape is to be moved, just assign InlineShape.Range.FormattedText to the target Range. Or, extend a range with text to also include the InlineShape. As far as Word is concerned, an InlineShape is a character.
To achieve the stated end goal
take text + an image that is aligned in a table (text left, image
right), break it out of the table, but maintain that left/right nature
use a table with an additional column, on the right. Put the image in it as an InlineShape. Then the entire row can be handled, for example as follows.
This creates a new row in the desired position, copies the Range.FormattedText of the row to be moved to the new row. Removes the additional row this creates and also deletes the original row.
Sub MoveRow()
Dim tbl As Word.Table
Dim rwToMove As Word.Row
Dim rwTarget As Word.Row
Dim rwBeforeTarget As Word.Row
Dim posNewRow As Long
posNewRow = 1
Set rwToMove = Selection.Rows(1)
Set tbl = rwToMove.Range.Tables(1)
Set rwBeforeTarget = tbl.Rows(posNewRow)
Set rwTarget = tbl.Range.Rows.Add(rwBeforeTarget) '(posNewRow)
rwTarget.Range.FormattedText = rwToMove.Range.FormattedText
tbl.Rows(posNewRow + 1).Delete
rwToMove.Delete
End Sub

VBA word stop merging cells adds new lines to merged cell

I have a table in word in which I merge 1 cell with text to the 2 empty cells left of it. Each time it merges it adds a new line under the text of the merged cell. This messes up the whole layout of the table. This table has been copied from Excel and pasted into Word. How do I fix this?
Dim table1 as Table
With table1
.Cell(Row:=1, Column:=3).Merge _
MergeTo:=.Cell(Row:=1, Column:=5)
End With
This variation includes two solutions for how to deal with existing content in cells being merged.
Private Sub TestMerge()
Dim i As Long
With ActiveDocument.Tables(1).Rows(1)
For i = 3 To 4
' .Cells(i).Range.Text = ""
.Cells(2).Merge .Cells(i)
Next i
.Cells(2).Range.Text = ""
End With
End Sub
The first solution deletes everything in cells 3 and 4 but retains content of cell(2). In the above code it is rendered mute by the apostrophe preceding the code.
The second way is to remove everything from the merged cells. I would recommend to run this version only while Application.ScreenUpdating = False because it will cause a lot of flicker.
There are several more way, but in order to recommend the one most suitable for your needs one would need to have a better understanding of what you want. BTW, if at all possible, remove the blanks from the table at the time they are entered. Having blanks floating around your document and popping up when they are least expected or wanted is never a good idea.
The Merge command can only merge two adjacent cells. You might use a loop to merge more cells.
Dim i As Long
With ActiveDocument.Tables(1).Rows(1)
For i = 3 To 4
.Cells(2).Merge .Cells(i)
Next i
End With
Cells 3 and 4 are merged with cell(2).

Moving page when pasting items

First of all sorry for not including any code from my attempts as I don't even know where to begin to start trial coding. What Im trying to do is I have a sheet which I have pre formatted to be my report. I then use a macro to copy certain columns from one sheet to the report sheet. I need to report sheet to be singed by somebody in the business and therefore need the bottom few rows for that. My question is how do I get the pasted columns to paste onto the next sheet if they reach a line that I decided is the last line I would like any information on. I apologise for the very vague question so please ask questions if you need any more info.
Loop Horizontal page breaks. Something like this.
For x = 1 To .HPageBreaks.Count - 1
MsgBox .HPageBreaks(x).Location.Row
'Write your rows adding your "sheet" row value to the pagebreak rows.
ws.Range("D" & lRow + .HPageBreaks(x).Location.Row).Value = "SomeValue"
Next

Add line and drag down certain content

I have a document which is used to list staff requests. I want a button to add a new row (new staff request) and insert certain things into columns automatically. So I want it to generate the next ref# (XX-01/XX-02 etc.) in one column and also add in the date the request was raised.
Is this possible?
Copy (not by OP) of comment:
The current code I use is:
Private Sub CommandButton1_Click()
Sheets("Sheet2").Range("A11").Select
ActiveCell.EntireRow.Insert Shift:=xlUp
Sheets("Sheet2").Range("A11:AA11").Select
Selection.Borders.Weight = xlThin
Range("A11:AA11").Interior.Color = RGB(255, 255, 255)
End Sub
This adds a new row and formats it as required. However even if I record a new macro to drag down the required fields (ref# etc) the next time I add a row it's added above the previously added row (as row 11 becomes 12 and so will always be added above).
In view of the first comment above (etc) despite the tags you might like to consider non-VBA alternatives. Perhaps enter into a Table (Insert > Tables - Table), say with ="XX-"&ROW()-1 in the Request# column (which should automatically adjust when dragged down) and use Ctrl+; for entry of the date.