Adding spaces at the beginning of specific line

A

Amir

Hi!


I want to build a macro which will replace hanging indent with equivalent
number of spaces like " ".

I assume the user is using the Courier New font with the size set to 12.

I've started building it, but I don't know how to add the spaces at the
beginning of each line except for the first line in each paragraph.

Here is what i've got by now. The place where I thought about adding the
spaces is marked with ***

I would be pleased if you help me.

Kind Regards,
Amir.

=================================
Sub Macro1()

'Variables declaration and setting
Dim dcmMyDocument As Document, prgMyParagraph As Paragraph
Dim intNumberOfSpaces As Integer, intNumberOfLines As Integer
Dim blnHasHangingIndent As Boolean, blnHasFirstLineIndent As Boolean
Dim i As Integer, j As Integer

Set dcmMyDocument = ActiveDocument

For Each prgMyParagraph In dcmMyDocument.Paragraphs
'Each Paragraph variables declaration
blnHasHangingIndent = False
blnHasFirstLineIndent = False

'Defines the number of spaces that should be added to each line
intNumberOfSpaces = Abs(Round((prgMyParagraph.FirstLineIndent / 7.2),
0))

'Defines whether there is a hanging indent or first line indent
'The 7.2 number is the width in points of the Courier New font with the
size set to 12
'(Thanks to Helmut Weber and Klaus Linke who helped me to find that one
out!!!!!)
If (Round((prgMyParagraph.FirstLineIndent / 7.2), 0) < 0) Then
blnHasHangingIndent = True
End If
'Currently I want to concentrate only on the hanging indent solution so
the next 3 lines in the code has no meaning.
'If (Round((prgMyParagraph.FirstLineIndent / 7.2), 0) > 0) Then
' blnHasFirstLineIndent = True
'End If

'Cancels the hanging indent and the first line indent, then replaces the
hanging indent with spaces
If blnHasHangingIndent Then
prgMyParagraph.FirstLineIndent = 0
prgMyParagraph.LeftIndent = 0

'Defines the number of lines in the current paragraph
intNumberOfLines =
(prgMyParagraph.Next.Range.Information(wdFirstCharacterLineNumber) -
prgMyParagraph.Range.Information_
(wdFirstCharacterLineNumber))

'Supposed to loop through all the lines in the current paragraph,
starting from the second line
'(The i variable represents the current line in the specific
paragraph)
i = 2
Do While (i <= intNumberOfLines)
'***Here I want to add the spaces (intNumberOfSpaces times) at
the beginning of each line, except for the first line
For j = 1 To (intNumberOfSpaces)
'***Add Space at the beginning of the 'i' line
Next j
i = i + 1
Loop

End If

Next

End Sub
 
A

Amir

Solved that one with the following sub procedure.

Regards,

Amir.

=============
'Variables declaration and setting
Dim dcmMyDocument As Document, prgMyParagraph As Paragraph
Dim intNumberOfLines As Integer
Dim blnHasHangingIndent As Boolean, blnHasFirstLineIndent As Boolean
Dim i As Integer, j As Integer, k As Integer
Dim lngCurrentParagraph As Long, lngParagraphsCount As Long,
arNumberOfLinesAndSpaces(1 To 10000, 1 To 3) As Integer
Dim blnWasOvertype As Boolean

'Changes mouse pointer to hourglass
System.Cursor = wdCursorWait

'Determines if the user is in Insert or Overwrite mode and changes to Insert
mode
blnWasOvertype = Options.Overtype
Options.Overtype = False

'Adding extra paragraph at the end of the document
SendKeys "^" & "{END}", True
SendKeys "{ENTER}", True

Set dcmMyDocument = ActiveDocument

'Determines How many paragraphs there are in the active document
lngParagraphsCount = dcmMyDocument.Paragraphs.Count

lngCurrentParagraph = 1
For Each prgMyParagraph In dcmMyDocument.Paragraphs

'Each Paragraph variables setting
blnHasHangingIndent = False
blnHasFirstLineIndent = False

'Determines How many lines there are in each paragraph Except for the
last one (which was added by the script)
If lngCurrentParagraph < lngParagraphsCount Then
arNumberOfLinesAndSpaces(lngCurrentParagraph, 1) =
prgMyParagraph.Next.Range.Information(wdFirstCharacterLineNumber) -
prgMyParagraph.Range.Information(wdFirstCharacterLineNumber)
End If

'Defines whether there is a hanging indent or first line indent
If (Round((prgMyParagraph.FirstLineIndent / 7.2), 0) < 0) Then
blnHasHangingIndent = True
End If
If (Round((prgMyParagraph.FirstLineIndent / 7.2), 0) > 0) Then
blnHasFirstLineIndent = True
End If

'Defines the number of spaces that should be added to each line
arNumberOfLinesAndSpaces(lngCurrentParagraph, 2) =
Abs(Round((prgMyParagraph.FirstLineIndent / 7.2), 0))

'Cancels the indents in the current paragraph
If blnHasHangingIndent Then
arNumberOfLinesAndSpaces(lngCurrentParagraph, 3) = 1 'Has only
hanging indent
prgMyParagraph.FirstLineIndent = 0
prgMyParagraph.LeftIndent = 0
End If
If blnHasFirstLineIndent Then
If Not (blnHasHangingIndent) Then
arNumberOfLinesAndSpaces(lngCurrentParagraph, 3) = 2 'Has only
first line indent
Else
arNumberOfLinesAndSpaces(lngCurrentParagraph, 3) = 3 'Has both
indents
End If
prgMyParagraph.FirstLineIndent = 0
End If

lngCurrentParagraph = lngCurrentParagraph + 1

Next

'Removes all list numbers and paragraph numbers
dcmMyDocument.RemoveNumbers

'Loops thruogh each one of the paragraphs and adds the \number of spaces
needed
SendKeys "^" & "{HOME}", True

For i = 1 To lngParagraphsCount 'i represents the paragraph
For j = 1 To arNumberOfLinesAndSpaces(i, 1) 'j represents the line in
each paragraph
Select Case arNumberOfLinesAndSpaces(i, 3)
Case 1 'Has only hanging indent
If (j <> 1) Then
SendKeys "{DOWN}", True
SendKeys "{HOME}", True
SendKeys "{ENTER}", True
For k = 1 To arNumberOfLinesAndSpaces(i, 2) 'k
represents the number of spaces that should be added
SendKeys " ", True
Next k
End If
Case 2 'Has only first line indent
Case 3 'Has both indents
End Select
Next j
SendKeys "^" & "{DOWN}", True
Next i

'Removes the extra paragraph at the end of the document
SendKeys "^" & "{END}", True
SendKeys "{BACKSPACE}", True

'Restores the Overtype mode to be as before the script started running
Options.Overtype = blnWasOvertype

System.Cursor = wdCursorNormal
 
H

Helmut Weber

Hi Amir,

have you thought about paragraphs reaching
from one page to next one ?

And all that sendkeys commands
may cause trouble in the long run.

Greetings from Bavaria, Germany

Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
http://word.mvps.org/
 
A

Amir

Hi!

I haven't thought about the pages problem,
but is there any problem with paragraphs reaching more than one page?
There are no 'pages' in my emulation program
(just a series of many 'lines').

I agree that sendkeys are bad, but I couldn't think of any better
solution to cut the paragraphs in every line except for putting
an 'Enter' there.. I will be happy to hear of any idea about that..

Kind Regards,
Amir.
 
H

Helmut Weber

Hi Amir,
wdFirstCharacterLineNumber is relative to the page.
But if you got no pages, though I hardly can imagine
how to achieve that, it might work.

For the sendkeys issue, I'd suggest to ask
in detail, what you want to do.

I think all those sendkeys could and should be replaced.

Greetings from Bavaria, Germany

Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
http://word.mvps.org/
 
A

Amir

Hi,

Now I understand what you mean...
That thing with the pages might be a problem.
What i'm trying to do is to convert a Word document to a format which does
not have indents,
and replace the indents (regular and hanging indents) with equivalent number
of spaces.
Therefore, I use the SendKeys to "break" the indents and then adds the
number of spaces
needed according to the indent.

I need that in order to paste that text into an emulation program which
doesn't read
Word's indents but spaces.

Can you think of a more simple way for doing that?
I can live with using SendKeys but I'm concerned about that problem
you've mentioned with the line counting, and despite my searches all over
the help documents and MSDN, couldn't find a way to solve that...

Thank you!,
Amir.
 
H

Helmut Weber

Hi Amir,

that is tedious work, but I don't know of a better way,
but to check what paragraph the selection is in, and
moving it down, until the number of the paragraph changes.

Everything you do with sendkeys can accomplished.

You only have to inform us about what you want to do.
Like this:
'Removes the extra paragraph at the end of the document
SendKeys "^" & "{END}", True
SendKeys "{BACKSPACE}", True

activedocument.paragraphs.last.range.delete

Or

GotoStartOfFirstParagraphInTheSelection

Selection.Paragraphs(1).Range.Select
Selection.Collapse

A million ways.

HTH

Greetings from Bavaria, Germany

Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
http://word.mvps.org/
 
A

Amir

OK, I'll try to list the tasks that I don't know how to do:

All these tasks are done inside the next loop:
For Each prgMyParagraph In dcmMyDocument.Paragraphs
Next

1. Determine how many lines there are in each paragraph.
(I've tried to use prgMyParagraph.Next.Range.Information_
(wdFirstCharacterLineNumber) - prgMyParagraph.Range_
.Information(wdFirstCharacterLineNumber)
But that produces an error when prgMyParagraph is
the last paragraph in the document because it can't
calculate the .Next.

2. Determine for each paragraph all the values of the indent.
I've solved that by using:
If (Round((prgMyParagraph.FirstLineIndent / 7.2), 0) < 0) Then
blnHasHangingIndent = True
End If
If (Round((prgMyParagraph.FirstLineIndent / 7.2), 0) > 0) Then
blnHasFirstLineIndent = True
End If

** - Here I still have a problem with the autonumbering,
because I don't know how to determine the indent caused
by the autonumbering! How can I know that?
I'm using ActiveDocument.ConvertNumbersToText,
but I don't know how many spaces to add starting from
the second ('hanging') line to each line that was
previously autounumbered!

The part which converts the hanging (not caused by
autonumbering) indent works fine, because I'm using
an array which saves for each paragrph the amount
of spaces that should be added to this paragraph
instead of the hanging indent (starting from the
second line of each paragraph because it's hanging).
Here is what I do to calculate that:

'Defines the number of spaces that should be added to each line
'instead of the indent after the indent is canceled
arNumberOfLinesAndSpaces(lngCurrentParagraph, 2) =
Abs(Round((prgMyParagraph.FirstLineIndent / 7.2), 0))

The first argument in the array saves the number of the
paragraph which it's indent values are currently
calculated, and the second argument says which
information about the paragraph is saved:

arNumberOfLinesAndSpaces(, 1 ) - Tells for each
paragraph, How many lines there are in this paragraph?

arNumberOfLinesAndSpaces(, 2 ) - Tells for each
paragraph, How many spaces should be added to
each line in order to replace the indent?

arNumberOfLinesAndSpaces(, 3 ) - Tells the type
of the indent in the specific paragraph:
1 - indicates hanging indent
2 - indicates first line indent
3 - will indicate autonumbering indent?
(but I don't know how to identify autonumbering
indent, and, in addition, if there is a way to do so,
should I use the Paragraph range? or maybe
the Sentence Range?


Your help is needed...


Thank you very much!!

Kind Regards,
Amir.
 
J

Jean-Guy Marcil

Amir was telling us:
Amir nous racontait que :
Hi,

Now I understand what you mean...
That thing with the pages might be a problem.
What i'm trying to do is to convert a Word document to a format which
does not have indents,
and replace the indents (regular and hanging indents) with equivalent
number of spaces.
Therefore, I use the SendKeys to "break" the indents and then adds the
number of spaces
needed according to the indent.

I need that in order to paste that text into an emulation program
which doesn't read
Word's indents but spaces.

Can you think of a more simple way for doing that?
I can live with using SendKeys but I'm concerned about that problem
you've mentioned with the line counting, and despite my searches all
over the help documents and MSDN, couldn't find a way to solve that...

If you are using Word 2003, you can take advantage of the new Page and Line
collections:

'_______________________________________
Dim myPane As Pane
Dim myPage As Page
Dim myRect As Rectangle
Dim myLine As Line
Dim LineRge As Range
Dim i As Long
Dim j As Long
Dim k As Long

Set myPane = ActiveWindow.ActivePane

With myPane
For i = 1 To .Pages.Count
Set myPage = .Pages(i)
With myPage
For j = 1 To .Rectangles.Count
Set myRect = .Rectangles(j)
With myRect
If .RectangleType = wdTextRectangle Then
For k = 1 To .Lines.Count
Set myLine = .Lines(k)
With myLine
If .LineType = wdTextLine Then
'Skip lone ¶
If Not .Range.Text = Chr(13) Then
Set LineRge = .Range
With LineRge
MsgBox .Text
'Do what you have to with this
range
'I guess it would be easier to
call a function
'and to pass it the line range
object
End With
End If
End If
End With
Next
End If
End With
Next
End With

Next
End With
'_______________________________________

But watch out, the rectangle collection includes header, footers, text
boxes, etc... So you may have to account for that in your code. The Line
collection also distinguished between a text line and a table row.

HTH.
--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
A

Amir

Hi!,

Thank you very much for the detailed answer,
but unfortunatly I can't use Office 2003 at that computer.

Is there a way I can check to see if a specific paragraph
is bulleted / numbered, and the properties of the
specific paragraph's numbering?

Guess I'm selecting a paragraph using:
Selection.Expand Unit:=wdParagraph

As a user (not with VBA) I can go to the
Format -> Bullets and Numbering menu,
and check to see if there is a blue rectangle on the
activate numbering method of the paragraph i've just selected.

Is there any way to do that with VBA?
In addition, how can I check the properties of this numbering/bulleting?
(the one which is activated on the paragraph I've selected)


At the help documents I saw something like:
With ListGalleries(wdNumberGallery).ListTemplates(7).ListLevels(1)
intIndentNumberPosition = .NumberPosition
intIndentTabPosition = .TabPosition
intIndentTextPosition = .TextPosition
intIndentStartAt = .StartAt
End With

but that doesn't tell me the current selected paragraph's properties!

Any help will be appreciated!

Regards,
Amir.
 
J

Jean-Guy Marcil

Amir was telling us:
Amir nous racontait que :
Hi!,

Thank you very much for the detailed answer,
but unfortunatly I can't use Office 2003 at that computer.

Is there a way I can check to see if a specific paragraph
is bulleted / numbered, and the properties of the
specific paragraph's numbering?

Guess I'm selecting a paragraph using:
Selection.Expand Unit:=wdParagraph

As a user (not with VBA) I can go to the
Format -> Bullets and Numbering menu,
and check to see if there is a blue rectangle on the
activate numbering method of the paragraph i've just selected.

Look up the help in the VBE on ListFormat and its properties, for example:

Selection.Paragraphs(1).Range.ListFormat.ListType

will return the kind of Bullet/numbering (if any) of the currently selected
paragraph.

If you are going to go through every paragraph, use the paragraph
collations, as in:

'_______________________________________
Dim MyParRge As Range
Dim i As Long

With ActiveDocument.Paragraphs
For i = 1 To .Count
Set MyParRge = .Item(i).Range
With MyParRge
Select Case .ListFormat.ListType
Case wdListBullet
MsgBox "Paragraph " & i & " has bullets"
Case wdListSimpleNumbering
MsgBox "Paragraph " & i & " has simple numbering"
Case wdListOutlineNumbering
MsgBox "Paragraph " & i & " has outline numbering"
Case wdListNoNumbering
MsgBox "Paragraph " & i & " has no numbering"
End Select
End With
Next
End With
'_______________________________________

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
H

Helmut Weber

Hi Amir,

as far as I see, question number 1 is enough of a challenge.

Such a seemably simple thing like counting
the lines in a paragraph turns out to be hell.

And I got a feeling, that the rectangle approach of Jean-Guy
won't work if the paragraph reaches over more than one page.
Besides that you haven't got Word 2003. And neither have I.

Not to speak of paragraphs that include a manual page break.
In that case,
selection.paragraphs(1).range.select
stops at the page break.

If you can definitely exclude manual page breaks,
then hopefully like this, for getting the number
of lines in a paragaph:
 
H

Helmut Weber

Sorry,
was hitting the wrong button:

Public Function PrgNum() As Long
' get number of paragraph
Dim rTmp As Range
Selection.Collapse
Set rTmp = Selection.Range
rTmp.Start = 0
rTmp.End = Selection.Range.End + 1
PrgNum = rTmp.Paragraphs.Count
End Function
' ----
Public Function PrgLines() As Long
Dim l As Long
Dim p1 As Long ' starting paragraph
p1 = PrgNum ' actual paragraph
l = 1
Selection.Paragraphs(1).Range.Select
Selection.Collapse
Selection.MoveDown
Selection.Bookmarks("\line").Select
Selection.Collapse direction:=wdCollapseStart
While p1 = PrgNum
' as long as the selection is in
' the starting paragraph
Selection.MoveDown
l = l + 1
If IslastLine Then
l = l + 1
GoTo weiter
End If
Wend
weiter:
PrgLines = l
Selection.MoveUp
Selection.Paragraphs(1).Range.Select
Selection.Collapse
End Function
' ----
Public Function IslastLine() As Boolean
On Error GoTo ende
If Selection.Bookmarks("\line").Range.End = _
ActiveDocument.Range.End - 1 Then
IslastLine = True
Else
IslastLine = False
End If
Exit Function
ende:
IslastLine = True
End Function
' ------
Sub test12345()
MsgBox PrgLines
End Sub
' ---------
Sub test777()
MsgBox IslastLine
End Sub

This is endlessly complicated.

You need a function to tell you,
what paragraph the selection is in: PrgNum
You need a function to count the lines in
a paragraph: PrgLines
You need a function to tell you,
whether a line is the last line in a doc: IslastLine.

Not regarding manual page breaks!

I wish I was paid for this.

Greetings from Bavaria, Germany

Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
http://word.mvps.org/
 
A

Amir

Hi!

This is brilliant!!

unfortunately I have to leave that problem for some days,
since I had too many difficulties by now and not much of success.
I hope to get back to it in the next few weeks, then this solution will help
me very much.
I can live without the manual page breaks.

I thank you very much for your help!!

Kind Regards,
Amir.
 
A

Amir

Hi,

Thank you for the answer!

Is there any way I can get more details about the
current paragraph's numbering, e.g. text position and number position?

I know that I can use (MyParagraph).Range.ListFormat.ListString
to get the list string, but how can I get the .StartAt, .TextPosition,
..TabPosition and .NumberStyle parameters of the CURRENT paragraph?
I want to get these parameters about a selected paragraph or about
a paragraph which I will define it's number by variable. e.g.
intParagraphNumber.

I thought about using ListGalleries(wdNumberGallery).ListTemplates_
(CurrentParagraphNumber).ListLevels.Item (1)
but will that give me the parameters about a specific paragraph?

Regards,
Amir.
 
J

Jean-Guy Marcil

Amir was telling us:
Amir nous racontait que :
Hi,

Thank you for the answer!

Is there any way I can get more details about the
current paragraph's numbering, e.g. text position and number position?

I know that I can use (MyParagraph).Range.ListFormat.ListString
to get the list string, but how can I get the .StartAt, .TextPosition,
.TabPosition and .NumberStyle parameters of the CURRENT paragraph?
I want to get these parameters about a selected paragraph or about
a paragraph which I will define it's number by variable. e.g.
intParagraphNumber.

I thought about using ListGalleries(wdNumberGallery).ListTemplates_
(CurrentParagraphNumber).ListLevels.Item (1)
but will that give me the parameters about a specific paragraph?

First, get the current paragraph outline level, if any. if there is one,
then use the something like:

'_______________________________________
Dim MyPara As Range
Dim MyLevel As Long
Dim MyStart As Long
Dim MyTextPos As Single
Dim MyTabPos As Single
Dim MyNumAlign As Long
Dim MyNumPos As Single
Dim MyNumStyle As Long

Set MyPara = Selection.Paragraphs(1).Range

With MyPara
MyLevel = .ListFormat.ListLevelNumber
MyStart = .ListFormat.ListTemplate.ListLevels(MyLevel).StartAt
MyTextPos =
PointsToInches(.ListFormat.ListTemplate.ListLevels(MyLevel).TextPosition)
MyTabPos =
PointsToInches(.ListFormat.ListTemplate.ListLevels(MyLevel).TabPosition)
MyNumPos =
PointsToInches(.ListFormat.ListTemplate.ListLevels(MyLevel).NumberPosition)
MyNumAlign = .ListFormat.ListTemplate.ListLevels(MyLevel).Alignment
MyNumStyle = .ListFormat.ListTemplate.ListLevels(MyLevel).NumberStyle
End With
'_______________________________________

If you can, avoid working with .ListGallery. This is a can of worm than can
only lead to disaster in the long run. It is very unstable and can produce
different results depending on the machine where it is used, unless you have
very long and complicated code to clean it up (I mean the Bullet and
numbering dialog box) Overall, it is not worth it.
--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top