functioning with objects of word document - vb6

I need to place three objects on my .doc in this order:
One Picutre;
Some Text;
One Table;
I recently learned how to place the image where I want (top of the doc).
But now, the table is getting in the middle of the text, how may I set the text with something like Position Absolute and then the Table below the text ?!
My Currently code:
Private Sub Command1_Click()
Dim Word_App As Word.Application
Dim Word_Doc As Word.Document
Dim Word_Table As Word.Table
Dim Word_Range As Word.Range
Dim iCount As Integer
'Insert the image
Word_App.Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
Word_App.Selection.InlineShapes.AddPicture FileName:="C:\p\53.jpg", SaveWithDocument:=True
Word_App.Selection.TypeParagraph
With Word_App
'Here I place some text
End With
'Insert Table
Set Word_Table = Word_Doc.Tables.Add(Range:=Word_Doc.Range(Start:=20, End:=20), NumRows:=3, NumColumns:=4, DefaultTableBehavior:=wdWord9TableBehavior, AutoFitBehavior:= _
wdAutoFitFixed)
Word_Doc.SaveAs FileName:="C:\p\TestandoPicture"
Set Word_Table = Nothing
Set Word_App = Nothing
Set Word_Doc = Nothing
End Sub
Here is an example of the result:
Notice that: In my code, I typed the position for my table Start:=20, End:=20 and it's in the 20th position of character... But i'd like to place it below the text... Wich is the best way to do so ?

Highlight the text, do a word count on the highlighted text, then use the character count from that to position your table. Crude but effective.

Related

Fill down formula in column gives 400 error

I am going to be splitting an incorrect url string in a column and need to use a formula to split it into separate columns. I have an empty column "H" next to column "G" which holds the incorrect url strings. Below you will see that I am trying to set "leftURL" to a formula and then copy it down the entire column. This works fine using regular Excel but when I try to do it as VBScript I get a 400 error:
Sub formulaLeft()
Worksheets("Feed Original").Activate
Dim lngLastRow As Long
Dim leftURL As Variant
leftURL = "=IF(ISNUMBER(SEARCH('%20',G2)),(LEFT(G2,FIND('%20',G2)-1)),G2)"
Sheets("Feed Original").Range("H2").Value = leftURL
lngLastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("H2:H" & lngLastRow).Value = leftURL
End Sub
What am I doing wrong?

Is there a way to associate data with an MSFlexGrid cell that is not displayed to the user?

Say I've got your standard MSFlexGrid. I have an image in a cell that already has a tooltip.
What I want to do is store a string about the image in the cell that's associated with the cell but is not displayed to the end user.
I've been looking at the properties on the MSDN website but I didn't see anything that would work.
Is this possible? Has anyone done something similar before? I'm not opposed to using properties that were not necessarily designed for data storage in this sense provided they're not being used already, but obviously this is not desirable.
So here's what I did for those who may be looking to do the same. It's not elegant, it's not pretty, but it works.
Private m_colImageInfo As Collection ' dictionary to store image name Key="Index^m_Tracker Row^Column" Value=IconKey
Private m_colImageInfoSorted As Collection ' Dictionary to store image name Key="Index^FG Row^Column" Value=IconKey
Private m_colSortRowInfo As ACCollection ' How the row changes
I have a function, called DoDisplay() that gets called everytime the grid is refreshed or initially displayed.
In it, I clear the m_colSortRowInfo Collection (ACCollection is just a wrapper we've built).
Call m_colSortRowInfo.Clear ' Note ACCollection allows the use of Clear
Now in do display we're grabbing data from the model, and get the actual image with the first DoAction call, and then get the image key (unique identifier about the image) with the second call.
Set oImage = m_Tracker2.DoAction(TS_ACTION_GET_COL_ICON, lRow, lColumn, False) 'Retrieve the icon image ' get the image
sString = m_Tracker2.DoAction(TS_ACTION_GET_COL_ICON, lRow, lColumn, True)
If Len(sString) > 0 Then
On Error Resume Next
Call m_colSortRowInfo.Add(CStr(.Index & "^" & lRow & "^" & .Col)) ' lets store the old key as a value for later access
Call m_colImageInfo.Add(sString, CStr(.Index & "^" & lRow & "^" & .Col))
On Error GoTo 0
End If
Then I add the icon key to m_colImageInfo as the Collection's "item" and the key being the grid Index^m_TrackerRow^Column.
To the m_colSortRowInfo I set the the same value (Index^m_TrackerRow^Column) as the item and then the key is just a simple iterative index.
Now the problem I was encountering was that these images exist in the grid, but I don't know anything about them besides that the cell contains, or doesn't contain an image / text. I need to associate the icon key with the image for reasons irrelevant to this post.
So now, we've gotten the grid, row and column of the model that the image is in, but we don't know where it actually lies in the grid. The column stays the same, but based on how the user has sorted the grid, the rows can change. This is the key challenge.
We have a way to map the model grid row to a specific MSFlexGrid row. I use that in the method below to populate m_colImageInfoSorted, which is the actual representation of each image in the grid.
'------------------------------------------------------------------
' NAME: SortImageCollection (PRIVATE)
' DESCRIPTION: When we first create the flex grid we pull the images from
' the image provider service and scale them up unfortunately there is
' no reference to the image that gets back. So what we do is create a
' collection to keep track of the image location and then send it to
' the printing class. If the grid has been sorted however, we need to
' identify where that picture moved too. This sub serves that purpose.
' KEYWORDS: sort, icon, collection, image
' CALLED BY: DoDisplay
' PARAMETERS:
' Index (I,REQ) - FlexGrid index
' RETURNS: nothing
' ASSUMES:
' SIDE EFFECTS: populates m_colImageInfoSorted with image keys in the fg grid
' with index passed to the function
'------------------------------------------------------------------
Private Sub SortImageCollection(Index As Integer)
Dim lCnt As Long
Dim lNumImages As Long
Dim lColumn As Long
Dim lRow As Long
Dim lOldRow As Long
Dim lCurGrid As Long
Dim sTempIconStr As String
Dim sOldKey As String
Dim sNewKey As String
Set m_colImageInfoSorted = Nothing
Set m_colImageInfoSorted = New Collection
With fgFlexGrid(Index)
For lNumImages = 1 To m_colSortRowInfo.Count ' we will loop over all the images
lCurGrid = CLng(Piece(m_colSortRowInfo.ItemVar(lNumImages), "^", 1, False)) ' if the grid is the grid we we asked for, then continue
If (lCurGrid = Index) Then ' we are just sorting images for this grid
For lCnt = 1 To m_lPatientRows(Index)
On Error Resume Next
lOldRow = CLng(Piece(m_colSortRowInfo.ItemVar(lNumImages), "^", 2, False)) ' get the m_tracker row we stored earlier
lRow = getRowFromFlexGrid(Index, lCnt) '
sOldKey = m_colSortRowInfo.ItemVar(lNumImages) ' get the old key
lColumn = Piece(sOldKey, "^", 3, False)
sTempIconStr = m_colImageInfo.Item(CStr(Index & "^" & lRow & "^" & lColumn)) '
sNewKey = CStr(.Index & "^" & lCnt & "^" & lColumn) ' get the column, add to new key
If (Len(sTempIconStr)) > 0 Then ' if we have an image (didn't already remove it)
Call m_colImageInfoSorted.Add(sTempIconStr, sNewKey) ' Add the new image location
End If
On Error GoTo 0
Next lCnt
End If
Next lNumImages
End With
End Sub
And wahlah, the call to the sub is all it takes:
Call SortImageCollection(Index)
I know that the SortImageCollection() sub is not the most efficient. If there is a better way to do this mapping, let me know, I'm interested in the response, but this is working well, and has no apparent slow down from an end user perspective so I'm happy with it.

Insert paragraph breaks before images

How can I create a macro to insert paragraph breaks before each image in a file?
If your images are of InlineShapes type then the code below will do the trick:
Sub InsertParagraphBeforeInlinShapes()
Dim iSHP As InlineShape
For Each iSHP In ActiveDocument.InlineShapes
ActiveDocument.Range(iSHP.Range.Start, _
iSHP.Range.Start).InsertParagraphBefore
Next iSHP
End Sub

Word delete blank lines

I would like to clean an auto-generated Word document.
This document contains several tables and there are many blank lines between each of them. I would like to develop a macro that only keeps one blank line between each table.
I don't know if it can be done. Now I'm stuck with:
Dim i As Integer
Dim tTable As Table
For i = 0 To ActiveDocument.Tables.Count
Set tTable = ActiveDocument.Tables.Item(i)
' ???
Next
Any idea?
I found how to do that:
Dim ParagraphToTrim As Range
Dim tTable As Table
Dim aTables() As Table
Set aTables = ActiveDocument.Tables
For Each tTable In aTables
' Supply a Start and End value for the Range.
Set ParagraphToTrim = ActiveDocument.Range(tTable.Range.Next(Unit:=wdParagraph).Start, tTable.Range.Next(Unit:=wdTable).Start)
' Keep at least a paragraph between each table
If ParagraphToTrim.Paragraphs.Count > 1 Then
With ParagraphToTrim
' Change the start of the range
.MoveStart Unit:=wdParagraph
.Delete
End With
End If
Next

How to save the text box values into an array?

I need to enter values in text box and when ever i press enter i have to save the text box values into an array.How can i achieve this functionality?
I would use a separate counter variable to redefine the size of the array, like this:
Option Explicit
Dim myArr() As String '~~~ dynamic array
Dim lngCnt As Long '~~~ a counter variable that keep track of the index
' inital stage..
Private Sub Form_Load()
lngCnt = 0
End Sub
' on KeyPress
Private Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then '~~~ if Enter Key is pressed..
ReDim Preserve myArr(lngCnt) '~~~ reclare the array with the new size, while preserving any elements it may contain
myArr(lngCnt) = Text1.Text '~~~ store the line
Text1.Text = "" '~~~ empty the textbox, so that you could type the next line
lngCnt = lngCnt + 1 '~~~ increment the counter, which we would use as size during the next keypress
End If
End Sub
' to display the elements
Private Sub Command1_Click()
Dim i As Long
For i = LBound(myArr) To UBound(myArr) '~~~ loop through the elements(from Lowerbound to Upperbound)..
Debug.Print myArr(i) '~~~ ..and display the item.
Next
End Sub
If you just want a new entry to be added each time they press the button, then use something like:
Redim Preserve YourArray(LBound(YourArray) To UBound(YourArray) + 1)
YourArray(UBound(YourArray)) = TextBox.Text
Note that this can get very slow and inefficient when the array contains large numbers of items as it's reallocating memory each time.
A better method would involve expanding the size of the array in chunks, while keeping track of the last valid entry.
Just give same name to all the text Boxes
The short answer is to use split to break the string up (you will need to tell the user what char to use to split on).
Long answer don't change the user interface to a repeater and have them use an input per value start here http://blogs.microsoft.co.il/blogs/basil/archive/2008/08/20/javascript-repeater-control-datarepeater-using-jquery-presenter-1-0-8-uicontrols-library.aspx
Else you will be debugging for ever.

Resources