Conditional Formatting in word vba - vba

Greeting to all Members and Experts, I am trying to automate
the formatting process in word. The formatting is done by applying styles. But before applying styles I need to trim extra spaces between characters of serial numbers, for example, 1. a. i. and insert tabs after dot(.) and then apply the style. I have attached a sample document. Plz have a look. I have tried to get the desired result by using the following code but it doesn't get the work done
I am new here so i dont know how to attach sample files so, here is the link for sample file. https://docs.google.com/document/d/1Z1dB6tvPKVrxHlw7qV8VNyiy49c5lRZN/edit?usp=sharing&ouid=101706223056224820285&rtpof=true&sd=true
Any help or suggestion would be of great help. Thanks in advance...
Sub formatts()
Dim a As Integer
Dim i As Integer, n As Long, para As Paragraph, rng As Range, doc As Document
Set doc = ActiveDocument
With doc
For i = 1 To .Range.Paragraphs.Count
For n = 1 To doc.Paragraphs(i).Range.Characters.Count
If .Paragraphs(i).Range.Characters(n).Text = " " Or .Paragraphs(i).Range.Characters(n).Text = Chr(9) Or .Paragraphs(i).Range.Characters(n).Text = Chr(160) Then
.Paragraphs(i).Range.Characters(n).Select
'This line checks whether the first character is whitespace character or not and delete it.
doc.Paragraphs(i).Range.Characters(n).Delete
ElseIf .Paragraphs(i).Range.Characters(n).Text = "." Then
.Paragraphs(i).Range.Characters(n).InsertAfter (vbTab)
n = n + 1
a = a + 1
ElseIf .Paragraphs(i).Range.Characters(n).Text Like "[a-z]." And .Paragraphs(i).Range.Characters(n).Next.Next.Text <> "i" Then
Exit For
End If
If a >= 3 Then Exit For
Next
For n = 1 To doc.Paragraphs(i).Range.Characters.Count
If .Paragraphs(i).Range.Characters(n).Text = "i" And .Paragraphs(i).Range.Characters(n).Next.Text = "." And .Paragraphs(i).Range.Characters(n).Next.Next.Text = " " Then
doc.Range.Paragraphs(i).Style = "shh"
Exit For:
ElseIf .Paragraphs(i).Range.Characters(n).Text = "a" Or .Paragraphs(i).Range.Characters(n).Text = "b" Or .Paragraphs(i).Range.Characters(n).Text = "c" And .Paragraphs(i).Range.Characters(n).Next.Text = "." And .Paragraphs(i).Range.Characters(n).Next.Next.Text = " " Then
doc.Range.Paragraphs(i).Style = "sh"
Exit For
End If
Next
Next
End With
End Sub

Related

vb.net position cursor one space greater than text box length

I have a TextBox and it contains this text "File Was Created"
I would like to place the cursor one space over from the end of this text in the TextBox
I am trying to NOT say Simple Enough Task BUT I have wasted 2 hours with no solution
YES I know if I change the text to this "File Was Created " it will work NOT a solution
Here is the code mess I have tried
Dim L As Integer
L = tbMessage.Text.Length
L += 1
'tbMessage.Text = CStr(L)
'tbHaveTwo.Text = frmOne.vR
'Me.ActiveControl = tbMessage
'tbMessage.SelectionStart = tbMessage.Text.Length
tbMessage.SelectionStart = L
tbMessage.Select()<br/>
Here is Two updated ways to solve this issue Jimi way less code
tbMessage.Text = "File Was Created"
'This Code involves more code
'Dim str As String
'str = Mid(tbMessage.Text, tbMessage.Text.Length)
'If str <> " " Then
' tbMessage.Text = tbMessage.Text & " "
'End If
'Answer from Jimi Works Great
tbMessage.AppendText(ChrW(32))
tbMessage.SelectionStart = tbMessage.Text.Length
tbMessage.Select()
So you don't end up with a ton of spaces on the end of your message?
tbMessage.AppendText(If(tbMessage.Text.EndsWith(" "), "", " "))
tbMessage.SelectionStart = tbMessage.TextLength
tbMessage.Focus()

VBA - Struggling with worksheet_change. Not working with no error given

I have a sheet in which our wholesale team are to enter L09 Part Codes and quickly see how much we have in stock of that item. The problem is that new starters may struggle to learn these part numbers as they don't follow a simple rule. What I did was create an easier code to remember which is simply: "Cable Type" & "Core Size" & "Cut Length", they also have the option to add "Colour" and "Brand" separated by spaces.
Their entered string may look like 6242y 2.5 100, or maybe 6242y 2.5 100 Grey, etc. and so where to look in my mapped table for what they've written depends on how many terms they put in. As you can see from the attached picture I need to select the correct column to look in for their code, and then offset back a few columns to suggest the correct L09 Part Number.
I hope the context makes a bit of sense and helps with the below code. The idea was for a new starter to enter something simple and it be replaced before their very eyes...
If anyone could help me to correct the following it would be greatly appreciated:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim P, Products, S, Search As Range
Dim Column As String
Dim Counter As Integer
Dim Spaces As Long
'On Error Resume Next
Counter = 0
'For top table only
If Target.Column = 1 And Target.Row < 100 Then
'Count spaces
Spaces = UBound(Split(Target, " "), 1)
Select Case Spaces
Case Is = 2
Column = "M"
Case Is = 3
Column = "O"
Case Is = 4
Column = "Q"
End Select
'When string has spaces
If Spaces <> 0 Then
'Set simple code range
Set Search = Sheets("Cherries").Range(Column & 1 & ":" & Column & 10000)
For Each S In Search
If S = Target Then
Target = S.Offset(0, 3 - 2 * Spaces)
End If
Next S
End If
Set Products = Sheets("Order Entry").Range("A3:A99")
For Each P In Products
If P.Value <> "" Then
Counter = Counter + 1
End If
Next P
Sheets("Order Entry").Rows("3:" & Counter + 11).Hidden = False
Sheets("Order Entry").Rows(Counter + 11 & ":99").Hidden = True
End If
End Sub
Unfortunately I'm not sure which line is erroring as no error message is given.
Thank you for your time.

VBA optimization robust code

So I'm completely new to VBA. I have a java-fetish so I'm not new to programming, however manipulating office documents just seemed easier with VBA.
Anyway, on topic:
I'm currently automating things in the company (This example is creating a contract). However, using Java, I always learned to make robust code and although the VBA code now works, I'm not happy with it because it requires a lot of 'friendliness' of the user. So my question is (I hope you don't mind), could you give me a nudge in the right direction to make my code way more robust?
Here's the code:
Function spaties(Name As String) As String
' Function used to ensure the length of a String (Working with Range)
Dim index As Integer
While (Len(Name) < 30)
Name = Name + " "
Wend
spaties = Name
End Function
Sub Macro3()
'
' Macro3 Macro
'
'
'ActiveDocument.Range(26101, 26102).Text = "d"
StartUndoSaver
Dim firma As String
firma = InputBox("Voor welke onderaannemer? (Zonder hoofdletters)" + Chr(10) + "(nicu, sorin of marius)")
Dim werf As String
werf = InputBox("Over welke Werf gaat het?")
Dim datum As String
datum = InputBox("Op welke datum spreekt het contract? (dd/mm/yyyy)")
With ActiveDocument
.Range(25882, 25899).Text = datum
ActiveDocument.Range(575, 605).Text = spaties(werf)
ActiveDocument.Range(1279, 1309).Text = spaties(werf)
End With
Select Case Len(firma)
Case 4
With ActiveDocument
.Range(26168, 26181).Text = "Nicu Dinita"
.Range(26062, 26088).Text = "Badi Woodconstruct SRL"
.Range(11359, 11371).Text = "Nicu Dinita"
End With
Case 5
With ActiveDocument
.Range(26168, 26181).Text = "Asavei Sorin"
.Range(26062, 26088).Text = "BELRO INTERIOR DESIGN SRL"
.Range(11359, 11371).Text = "Asavei Sorin"
End With
Case 6
With ActiveDocument
.Range(26168, 26181).Text = "Ivan Maricel"
.Range(26062, 26088).Text = "Solomon & Aaron Construct"
.Range(11359, 11371).Text = "Ivan Maricel"
End With
End Select
Dim prijs As String
Dim besch As String
Dim eenh As String
Dim hoev As Integer
hoev = InputBox("Hoeveel artikels zijn er?")
Dim index As Integer
index = 1
While (index <= hoev)
besch = InputBox("Beschrijving van het artikel (engels)")
prijs = InputBox("prijs van het artikel")
eenh = InputBox("Eenheid van het artikel")
With ActiveDocument
.Range(5701, 5702).Text = "" + vbTab + spaties2(besch, prijs, eenh) + Chr(10) + vbTab
End With
index = index + 1
Wend
With ActiveDocument.Sections(1)
.Headers(wdHeaderFooterPrimary).Range.Text = "Raes G. Schrijnwerken BVBA" + vbTab + vbTab + datum + Chr(10) + "Robert Klingstraat 5" + Chr(10) + "8940 Wervik"
.Footers(wdHeaderFooterPrimary).Range.Text = "Overeenkomst tot onderaanneming" + Chr(10) + "met betrekking tot:" + werf
.Footers(wdHeaderFooterPrimary).PageNumbers.Add PageNumberAlignment:=wdAlignPageNumberRight
End With
If firma = "sorin" Then
ActiveDocument.Range(254, 255).ImportFragment "Z:\Raes Netwerk DATA\professioneel\004 Sjablonen\belro.docx", False
Else
If firma = "nicu" Then
With ActiveDocument
.Range(254, 255).ImportFragment "Z:\Raes Netwerk DATA\professioneel\004 Sjablonen\Nicu.docx", False
End With
Else
If firma = "marius" Then
ActiveDocument.Range(254, 255).ImportFragment "Z:\Raes Netwerk DATA\professioneel\004 Sjablonen\Marius.docx", False
End If
End If
End If
ActiveDocument.PrintOut
ActiveDocument.PrintOut
End Sub
Function spaties2(artikel As String, prijs As String, eenh As String) As String
'Another function to ensure length of String
Dim index As Integer
Dim eind As String
eind = "" + artikel + vbTab + vbTab + prijs + "€/" + eenh
While (Len(eind) < 100)
eind = eind + " "
Wend
spaties2 = eind
End Function
As you can see, the code is very basic. And although it works, it's no good to deliver.
The two defined Functions are simply formatting the String of the user because obviously the name of something is not always the same length.
I'd like to cut out the Range properties, because in my opinion, that's what makes the program so sensitive to changes.
Any and all suggestions are welcome.
note: For the moment, the contract can have three different 'target parties' so that's why the Select Case statement is there. It's going to be completely useless if it should grow but for now it works.
Here's one:
sName = Left(sName & Space(30), 30)
And I think it's better to use bookmarks as placeholders instead of using Range(start, end)
How to change programmatically the text of a Word Bookmark
I think that your code needs some Trim's, in order to avoid mistaken spaces before and after the names (when you use some inputboxes, I mean).
And you need to verify input dates, too.
For string concatenation, use the ampersand (&) better than the plus sign (+), in order to avoid mistaken sums.
Instead of Chr(10) I have some recommendations in order to make your code more readable:
Chr(13) = vbCr
Chr(10) = vbLf
Chr(13) & Chr(10) = vbCrLf
Verify that the files you are indicating exist.
Using Range with numerical values is definitely not reliable. Bookmarks, as Tim suggests or content controls if this is Word 2007 or later. Content Controls are Microsoft's recommendation, going forward, but I don't see any particular advantage one way or the other for your purpose.
Looking at all the InputBox calls I have to wonder whether displaying a VBA UserForm for the input might not be better? All the input fields in one place, rather than flashing multiple prompts. You can validate for correct input before the UserForm is removed from the screen, etc.

VB - Index outside of bounds?

Oh my god i hate this thing, i tried millions of ways but couldn't find a working one. Let me explain:
I'm testing each line and checking the first word to be "copy" alright ? After the word copy i want to see if the next word is "1" , the third is "<" and the last is ">" , if all these conditions are fullfilled then the text between "<" and ">" needs to be stored in the variable "copy1" (even if there is more than 1 word between them).
What my code is:
For i = 0 To lstCode.Items.Count - 1
Dim str As String = lstCode.Items.Item(i)
Dim strA() As String = Split(str)
Dim copy1 as string
Dim copy2 as string
Select Case strA(0)
Case copy
If strA(1) = "1" And strA(2) = "<" And strA(strA.Count - 1) = ">" Then
copy1 = ""
For lr As Integer = 3 To strA.Count - 2
copy1 &= (strA(lr) & " ")
Next
End if
End select
And, when i debug it i get the error: Index was outside the bounds of the array ... Does anybody have any idea ?
There is something important i forgot to add, this is the whole code:
Case "copy"
If strA(1) = "1" And strA(2) = "<" And strA(strA.Count - 1) = ">" Then
copy1 = ""
For lr As Integer = 3 To strA.Count - 2
copy1 &= (strA(lr) & " ")
Next
ElseIf strA(1) = "2" And strA(2) = "<" And strA(strA.Count - 1) = ">" Then
copy2 = ""
For lrs As Integer = 3 To strA.Count - 2
copy2 &= (strA(lrs) & " ")
Next
ElseIf strA(1) = "run" Then
Try
IO.File.Copy(copy1, copy2)
Catch ex As IO.IOException
End Try
End If
End Select
So everything works like a charm: copy 1 < c:\csb.log > , copy 2 < c:\blabla.txt > but when the " copy run " statement comes in it gives me the error...
You need to change the operator And with AndAlso.
The second one applies Short Circuit Evaluation to your expression, meaning if the first expression is false the second, third and so on expressions on the same line are not evaluated.
In your line
If strA(1) = "1" And strA(2) = "<" And .......
when the value is "Run" you still evaluate the expression strA(2) = "<" but there is no element at index 2 so you get the error.

How to Count the Number of a Specific Character in a Cell with Excel VBA

I have a number of items in cells that are separated by dashes. I'm trying to normalize the database by splitting rows so that each row contains only one entry. How do you find/count strings in Excel VBA. I know you can do values for whole cells with
myVar = Application.WorksheetFunction.COUNTIF(Range("A1:Z100"),"Value")
I need to search a single cell and find out how many hyphens there are. Example
123-456-789 = 2
9876-12 = 1
Using hint from ron's function above I've created this formula and it worked fine :
=LEN(A1) - LEN(SUBSTITUTE(A1, "-", ""))
This will count the number of hyphens in the activecell
Sub test()
a = Len(ActiveCell)
my_txt = Replace(ActiveCell, "-", "", 1, -1, vbTextCompare)
b = Len(my_txt)
numb_occur = a - b
End Sub
Here's the UDF to count single string occurence in string:
Option Explicit
Function COUNTTEXT(ref_value As Range, ref_string As String) As Long
Dim i As Integer, count As Integer
count = 0
If Len(ref_string) <> 1 Then COUNTTEXT = CVErr(xlErrValue): Exit Function
For i = 1 To Len(ref_value.value)
If Mid(ref_value, i, 1) = ref_string Then count = count + 1
Next
COUNTTEXT = count
End Function
Here's using Array formula:
=SUM(IF(ISERROR(SEARCH("-",MID(A1,ROW(INDIRECT("$1:$" & LEN(A1))),1))),0,1))
Entered using Ctrl+Shift+Enter.
Hope this helps.
I found this answer:
Sub xcountCHARtestb()
'If countCHAR(RANGE("aq528"), ".") > 0 Then 'YES
If countCHAR(Selection, ".") > 0 Then 'YES
MsgBox "YES" & Space(10), vbQuestion ', "title"
Else
MsgBox "NO" & Space(10), vbQuestion ', "title"
End If
End Sub
Sub xcountCHARtesta() 'YES
MsgBox "There are " & countCHAR(Selection, "test") & " repetitions of the character string", vbQuestion 'YES
End Sub
Function countCHAR(myString As String, myCHAR As String) As Integer 'as: If countCHAR(Selection, ".") > 1 Then selection OR RANGE("aq528") '"any char string"
countCHAR = UBound(split(myString, myCHAR)) 'YES
End Function
This code might be of your help .. you can also use it as a UDF... :)
Function CountHypens(rng_Src As Range) As Long
'A VARIANT FOR SPLITTING CELL CONTENTS
Dim var As Variant
On Error Resume Next
var = Split(rng_Src.Value, "-", , vbTextCompare)
If Err.Number <> 0 Then
Debug.Print "This cell does not have any hyphens."
Else
CountHypens = UBound(var)
End If
Err.Clear: On Error GoTo 0
End Function
Follow up to: davex, by davex.. :)
I had been looking all over trying to find a way to test same for find text string in a formula.
This answer seems to work correctly for both formulas / not & fits in a 1 liner..
(am still pretty novice at vba, let me know if any better way(s) ) thanks.
If countChar(UCase(Selection.Formula), UCase("offset")) > 0 Then 'YES (thee? answer, works for both formulas / not)
'If countChar(Selection.Formula, "OFFSET") > 0 Then 'yes
'If countChar(Cells(ActiveCell.row, Selection.Column).Formula, "OFFSET") > 0 Then 'yes
'If countChar(Cells(ActiveCell.row, "BG").Formula, "OFFSET") > 0 Then 'yes
'If countChar(UCase(Selection), UCase("OffSET")) > 0 Then 'yes but not work on formula
'If Selection.Formula Like "*offset*" Then 'no (for eq)
MsgBox "YES" & Space(15), vbQuestion
Else
MsgBox "NO" & Space(15), vbQuestion
End If
NOTE: in place of variable "BG" above, i use permanent work cells to improve use for column BG example, work cell A3 has / shows: BG:BG
=SUBSTITUTE(SUBSTITUTE(CELL("address",$BG3),"$",""),ROW(),"")&":"&SUBSTITUTE(SUBSTITUTE(CELL("address",$BG3),"$",""),ROW(),"")
you will also need to dim the work cell, at the top / before the vba:
Dim A3 As String
A3 = RANGE("A3")
pardon, tried 3 times to get all of code into 1 box. really suggest putting a code stop start icon in the toolbar.