How do you format text/strings in VBA? - vba

In the code below, I take some input parameters, either text or a cell, and combine them to form one string using the formatting I need. I need to make Task_Name bold, as well as text like "Lead :". I know you cannot make text in a variable bold, but how do I go about this? This cell I'm storing the value in is eventually used in a Word mail merge.
I need to format part of a string. In the code below, I need to make Task_Name, "Lead : ", etc. all bold.
Function GENERATE_STAFFING_SECTION(Task_Name, Lead_By, Members, Instructions)
Dim tmpSection As String
If Len(Task_Name > 0) And Len(Lead_By) > 0 And Len(Members) > 0 And Len(Instructions) > 0 Then
tmpSection = vbLf _
& Task_Name _
& vbLf & "Lead : " & Lead_By _
& vbLf & "Ambassadors : " & Members _
& vbLf & "Instructions : " & Instructions _
& vbLf
Else
tmpSection = ""
End If
GENERATE_STAFFING_SECTION = tmpSection
End Function
Also, I know it's not the cleanest code, so if there are any other suggestions for improving it, they are most welcome.
Thanks!

You can't add anything to the string directly to make the cell have bold characters.
Once you've written the string out to the cell, you'll need to go back and reprocess the cell.
For example:
With ActiveCell.Characters(Start:=11, Length:=6).Font
.Name = "Arial"
.FontStyle = "Bold"
.Size = 10
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
End With
This snippet will set only a portion of the cell to bold.
EDIT:
This code could be used to implement the above and give you what you want.
It could be written better, but should give you an idea of what you've got to write:
Public Sub FormatOuput()
Dim i As Integer
'Format Task_name
i = InStr(1, ActiveCell.Text, vbLf)
MakeBold 1, i
'Format 'Lead'
MakeBold i + 1, 4
'Format 'Ambassadors'
i = InStr(i + 1, ActiveCell.Text, vbLf)
MakeBold i+1, 11
'Format 'Instructions'
i = InStr(i + 1, ActiveCell.Text, vbLf)
MakeBold i+1, 10
End Sub
Public Sub MakeBold(startPos As Integer, charCount As Integer)
With ActiveCell.Characters(start:=startPos, length:=charCount).Font
.Name = "Arial"
.FontStyle = "Bold"
.Size = 10
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
End With
End Sub

Related

Setting formatconditions doesn't work with certain ranges?

I have the following code:
i = i + 1
StrSearchCriteria = "=($W1=" & Chr(34) & "ETF" & Chr(34) & ")"
With .Range("A:A").FormatConditions
.Add Type:=2, Formula1:=StrSearchCriteria
With .Item(i)
.SetFirstPriority
With .Interior
.PatternColorIndex = xlAutomatic
.Color = RGB(225, 225, 0)
End With
.StopIfTrue = False
End With
End With
This does not set the format conditions. The rule is there and the range, criteria are correct, but the format conditions are "No Format Set".
HOWEVER.... if I change
With .Range("A:A").FormatConditions
to
With .Range("E:E").FormatConditions
It works...
"B:B", "C:C", "D:D" all fail with the same issue.
Using "E:E" (and I also tried "F:F" which worked), I can then open the workbook and manually change the range to "A:A", "B:B", "C:C" or "D:D" and it works.
I then tried "A:E", which also worked. It appears that if I use any part of column E through W (last column) it works, but if I don't include anything from E and following it fails.
Totally confused here. Any ideas?
Is there a merged cell range in A:D?
I believe #mer_curius hit on the issue - merged cells.
So, as a work around, since I only want A:A to have the coloring and I need to set the condition to A:E, I follow that rule with setting a rule with the same criteria and no-fill B:E.
The code that works looks like this:
i = 1
StrSearchCriteria = "=($W1=" & Chr(34) & "ETF" & Chr(34) & ")"
strRange = "A:E"
With .Range(strRange).FormatConditions
.Add Type:=2, Formula1:=StrSearchCriteria
With .Item(i)
.SetFirstPriority
With .Interior
.PatternColorIndex = xlAutomatic
.Color = RGB(225, 225, 0)
End With
.StopIfTrue = False
End With
End With
i = i + 1
StrSearchCriteria = "=($W1=" & Chr(34) & "ETF" & Chr(34) & ")"
strRange = "B:E"
With .Range(strRange).FormatConditions
.Add Type:=2, Formula1:=StrSearchCriteria
With .Item(i)
.SetFirstPriority
With .Interior
.Pattern = xlNone
End With
.StopIfTrue = False
End With
End With

For Loop and If statement. How to combine in one statement

I have the following for loop on my project:
'Range and Range Array variables
Dim rngArray As Object
Dim rngArrayMain(0 To 9) As Excel.Range
rngArrayMain(0) = xlWSEE.Range("I40")
rngArrayMain(3) = xlWSEE.Range("V46")
rngArrayMain(4) = xlWSEE.Range("L48:N48")
rngArrayMain(5) = xlWSEE.Range("L51")
rngArrayMain(6) = xlWSEE.Range("J35")
rngArrayMain(7) = xlWSEE.Range("J53")
rngArrayMain(1) = xlWSEE.Range("B57:B61")
rngArrayMain(2) = xlWSEE.Range("B70")
rngArrayMain(8) = xlWSEE.Range("L47")
rngArrayMain(9) = xlWSEE.Range("O47")
For Each rngArray In rngArrayMain
With rngArray
.Font.Bold = True
.Font.Size = 10
.Font.Name = "Calibri"
.Font.ColorIndex = 2 'white
End With
Next rngArray
No problem, works well. However, I have to separate the last two elements of my array because the Font.ColorIndex = 1 for them.
So basically my for loop would be:
if array 0-7
perform this action
if array 8-9
then perform this action.
How can I fix my code to reflect this change? If the question seems elementary it's because I have not been programming long and what I know is self-taught (google, bing, and a few books).
Thanks.
Use a For loop instead of a For Each, like this:
For i As Integer = 0 To rngArrayMain.Length - 1
' First seven items do this (index 0 to 6)
If i <= 6 Then
With rngArrayMain(i)
.Font.Bold = True
.Font.Size = 10
.Font.Name = "Calibri"
.Font.ColorIndex = 2 'white
End With
Else
' Last two items do this
With rngArrayMain(i)
.Font.Bold = True
.Font.Size = 10
.Font.Name = "Calibri"
.Font.ColorIndex = 1
End With
End If
Next
Note: If you remove the With block, then you would actually save lines of code, because you put the If logic around the one property that is different, like this:
For i As Integer = 0 To rngArrayMain.Length - 1
rngArrayMain(i).Font.Bold = True
rngArrayMain(i).Font.Size = 10
rngArrayMain(i).Font.Name = "Calibri"
If i <= 6 Then
rngArrayMain(i).Font.ColorIndex = 2
Else
rngArrayMain(i).Font.ColorIndex = 1
End If
Next
Dim cellsWithColor2 As Range
Dim cellsWithColor1 As Range
Dim xlWSEE As Worksheet
Set xlWSEE = Worksheets("FillTheNameHere")
Set cellsWithColor2 = Application.Union( _
xlWSEE.Range("I40"), _
xlWSEE.Range("V46"), _
xlWSEE.Range("L48:N48"), _
xlWSEE.Range("L51"), _
xlWSEE.Range("J35"), _
xlWSEE.Range("J53"), _
xlWSEE.Range("B57:B61"), _
xlWSEE.Range("B70"))
With cellsWithColor2
.Font.Bold = True
.Font.Size = 10
.Font.Name = "Calibri"
.Font.ColorIndex = 2 'white
End With
Set cellsWithColor1 = Application.Union( _
xlWSEE.Range("L47"), _
xlWSEE.Range("O47"))
With cellsWithColor1
.Font.Bold = True
.Font.Size = 10
.Font.Name = "Calibri"
.Font.ColorIndex = 1 'another color
End With

Automatic plotting of graphs from different sheet

I am programming an excel application that takes info from a Tables Sheet ( that it is also programmed and the length and position of each table can change) and generate a graphic for each table in other sheet, called Estimation Sheet, when a button is press.
I managed to do this task for the first graphich (corresponding to first table) but when I try to use the same method for the second...it doesn't work. This is the method used to draw the first graphic:
Public Sub generateGraphicsC(RowResistiveC As Integer)
Dim FirstRow As Integer, FirstColumn As Integer, LastRow As Integer, LastColumn As Integer, GraphLocation As Integer
Dim XelementsC As Integer, Yelements As Integer
Dim myChtObj As ChartObject
Dim rngChtData As Range
Dim rngChtXVal As Range
Dim i As Integer
Dim WSD As Worksheet
Set WSD = Worksheets(2) 'Data source
Dim CSD As Worksheet
Set CSD = Worksheets(3) 'ChartOutput
'Dim chrt As ChartObject
'Dim cw As Long
'Dim rh As Long
' get the current charts so proper overwriting can happen Dim chtObjs As ChartObjects
Set chtObjs = CSD.ChartObjects
WSD.AutoFilterMode = False ' Turn off autofilter mode
'Dim finalRow As Long ' Find the last row with data
'finalRow = WSD.Cells(Application.Rows.Count, 1).End(xlUp).Row
FirstRow = RowResistiveC
FirstColumn = 5
XelementsC = countXelementsC(FirstRow - 1, FirstColumn) 'Count the x Elements (amperes)
Yelements = countYelements(FirstRow) 'Count the y Elements (Combinations)
LastRow = FirstRow + Yelements - 1 'The last row and column I will read
LastColumn = FirstColumn + XelementsC - 1
'---------------------DRAW THE GRAPHIC----------------------------------------------'
' Delete any previous existing chart
'Dim chtObj As ChartObject
' define the x axis values
WSD.Activate
Set rngChtXVal = WSD.Range(Cells(FirstRow - 1, FirstColumn), Cells(FirstRow - 1, LastColumn))
' add the chart
Charts.Add
With ActiveChart
' make a XY chart
.ChartType = xlXYScatterLines
' remove extra series
Do Until .SeriesCollection.Count = 0
.SeriesCollection(1).Delete
Loop
.Location Where:=xlLocationAsObject, Name:="Estimation Sheets"
End With
'-----------------------------------------------------------------------------
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "Factor C"
'To Interpolate between the ungiven values
.DisplayBlanksAs = xlInterpolated
'TITLE STYLE
.ChartTitle.AutoScaleFont = False
With .ChartTitle.Font
.Name = "Calibri"
.FontStyle = "Bold"
.Size = 14
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
.Background = xlAutomatic
End With
'AXIS STYLE-----------------------------------------------------------------------
.Axes(xlCategory).TickLabels.AutoScaleFont = False
With .Axes(xlCategory).TickLabels.Font
.Name = "Arial"
.FontStyle = "Regular"
.Size = 10
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
.Background = xlAutomatic
With Selection.Border
.ColorIndex = 15
.LineStyle = xlContinuous
End With
End With
.Axes(xlValue).TickLabels.AutoScaleFont = False
With .Axes(xlValue).TickLabels.Font
.Name = "Calibri"
.FontStyle = "Regular"
.Size = 8
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
.Background = xlAutomatic
End With
End With
'-----------------------------------------------------------------------------
' HEIGHT; WIDTH AND POSITION
GraphLocation = CSD.Cells(Rows.Count, 2).End(xlUp).Row + 3
Dim RngToCover As Range
Set RngToCover = ActiveSheet.Range(Cells(GraphLocation, 2), Cells(GraphLocation + 20, 11))
With ActiveChart.Parent
.Height = RngToCover.Height ' resize
.Width = RngToCover.Width ' resize
.Top = RngToCover.Top ' reposition
.Left = RngToCover.Left ' reposition
End With
' for each row in the sheet
For i = FirstRow To LastRow
Dim chartName As String
' define chart data range for the row (record)
Set rngChtData = WSD.Range(WSD.Cells(i, FirstColumn), WSD.Cells(i, LastColumn))
'To get the serie name that I´m going to add to the graph
Dim serieName As String
Dim varItemName As Variant
WSD.Activate
varItemName = WSD.Range(Cells(i, 1), Cells(i, 4))
serieName = CStr(varItemName(1, 1) + " " + varItemName(1, 2) + " " + varItemName(1, 3) + " " + varItemName(1, 4))
' add series from selected range, column by column
CSD.ChartObjects.Select
With ActiveChart
With .SeriesCollection.NewSeries
.Values = rngChtData
.XValues = rngChtXVal
.Name = serieName
End With
End With
Next i
'We let as last view the page with all the info
CSD.Select
End Sub
I am calling this Sub from other one. The next step will be calling a similar method (exactly the same but other starting point to get the data and some different format properties)for other kind of table and graphic:
Public Sub printGraphics()
Modul4.ClearGraphs
Modul4.generateGraphicsC (RowResistiveC)
Modul4.generateGraphicsT (RowResistiveT)
End Sub
And so on. CountXelements and Yelements counts the number of elements from the Tables Sheet and RowResistiveC, for example, keeps the position of the table.
GenerateGraphicsC works but generateGraphicsT (exactly the same) crush in the line:
With .SeriesCollection.NewSeries
Whit error 91 ( I have a german version of excel at work but it's something like variable object or bloque object not given).
As I suspected the error came from :
CSD.ChartObjects.Select
That works in my solution for the first graph since I'm selecting the single graphic on the sheet, but when I add more it doesn´t.
I just changed that line for:
CSD.ChartObjects(1).Activate
and so on. It works perfectly. I also had to make some adjusments to avoid all the graphs being plotted over the previous one, but it works nice.

Codehelp: Seeking column, and format cells

I have a little problem with my macrocode, and need your advice. Here my base macrocode:
Option Explicit
Sub NurZumUeben()
'oberste Zeile löschen, fixieren und linksbündig ausrichten
Rows("1:1").Select
Selection.Delete Shift:=xlUp
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
End With
ActiveWindow.FreezePanes = True
'Jede zweite Zeile schattieren
Application.ScreenUpdating = False
Dim Zeile, ZeilenNr As Integer
With ActiveSheet.UsedRange.Rows
.Interior.ColorIndex = xlNone
.Borders.ColorIndex = xlNone
End With
ZeilenNr = 2
For Zeile = 2 To ActiveSheet.UsedRange.Rows.Count
With Rows(Zeile)
If .Hidden = False Then
If ZeilenNr Mod 2 = 0 Then
.Interior.ColorIndex = 15
.Borders.Weight = xlThin
.Borders.ColorIndex = 16
ZeilenNr = ZeilenNr + 1
Else
ZeilenNr = ZeilenNr + 1
End If
End If
End With
Next Zeile
Application.ScreenUpdating = True
'oberste Zeile einfärben
Rows("1:1").Select
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
'Spalte_suchen&formatieren
Dim iLeSpa As Integer
Dim iSpalte As Integer
Dim bGefunden As Boolean
iLeSpa = IIf(IsEmpty(Cells(1, Columns.Count)), Cells(1, _
Columns.Count).End(xlToLeft).Column, Columns.Count)
For iSpalte = 1 To iLeSpa
If Cells(1, iSpalte).Value = "click_thru_pct" Then
bGefunden = True
Exit For
End If
Next iSpalte
If bGefunden Then
With Range(Cells(2, iSpalte), Cells(5000, iSpalte))
.Replace What:="%", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows
Range("K1") = 100
Range("K1").Copy
.PasteSpecial Paste:=xlPasteAll, Operation:=xlDivide
.NumberFormat = "0.00%"
Range("K1").Clear
End With
Else
MsgBox "Die Überschrift ""click_thru_pct"" wurde nicht gefunden.", _
48, " Hinweis für " & Application.UserName
End If
End Sub
Once thank you all who can help. Unfortunately, I get the final formatting not go quite
Here are the results: example
I did not want to color the entire column but only the top row. In addition, the lower empty fields with ugly 0.00% formatted constantly.
Furthermore, I noticed that after the coloration of the first line, the field K1 is visible. That is with me unfortunately impractical because these Excel documents can also go differently in the row.
Here is the document on which you can test it if necessary.
example
Thank you very much
Change modular function to calculate the for loop variable. I see no purpose in using a separate variable for this. Change this:
ZeilenNr = 2
For Zeile = 2 To ActiveSheet.UsedRange.Rows.Count
With Rows(Zeile)
If .Hidden = False Then
If ZeilenNr Mod 2 = 0 Then
.Interior.ColorIndex = 15
.Borders.Weight = xlThin
.Borders.ColorIndex = 16
ZeilenNr = ZeilenNr + 1
Else
ZeilenNr = ZeilenNr + 1
End If
End If
End With
Next Zeile
To this:
For Zeile = 2 To ActiveSheet.UsedRange.Rows.Count
With Rows(Zeile)
If .Hidden = False Then
If Zeile Mod 2 = 0 Then
.Interior.ColorIndex = 15
.Borders.Weight = xlThin
.Borders.ColorIndex = 16
End If
End If
End With
Next Zeile
I apologize if I am missing something here. Also, I cannot view the examples you provided because the site requires a login and it is not in English. Sorry again.
Within your existing code,
Substitute 5000 with ActiveSheet.UsedRange.Rows.Count
Substitute Range("K1").Clear with Range("K1").ClearContents
Instead of For Zeile = 2 To ActiveSheet.UsedRange.Rows.Count, you could use
For Zeile = 2 To ActiveSheet.Range("A1").CurrentRegion.Rows.Count-1
.UsedRange is not always properly reset. You sample seems a good candidate for .CurrentRegion

How to avoid paragraph marks?

I have this routine that works well, but it messes up as it counts paragraph marks. How can I skip paragraph marks?
For Each wrd In ActiveDocument.Words
If Selection.Style = ActiveDocument.Styles("Normal") Then
If wrd.Font.Name <> "Arial" Or wrd.Font.Size < 9 Or wrd.Font.Size = 11 Or wrd.Font.Size > 12 _
Or wrd.Font.Color <> wdColorBlack Or wrd.Font.Color <> wdColorAutomatic Or wdColorBlue Then
wrd.HighlightColorIndex = wdYellow
wordrep = wordrep + 1
End If
End If
Next
Try this
For Each wrd In ActiveDocument.Words
If Selection.Style = ActiveDocument.Styles("Normal") Then
If wrd.Font.Name <> "Arial" Or _
wrd.Font.Size < 9 Or _
wrd.Font.Size = 11 Or _
wrd.Font.Size > 12 _
Or wrd.Font.Color <> wdColorBlack Or _
wrd.Font.Color <> wdColorAutomatic Or _
wrd.Font.Color <> wdColorBlue Then
If Asc(Left(wrd, 1)) <> 13 Then
wrd.HighlightColorIndex = wdYellow
wordrep = wordrep + 1
End If
End If
End If
Next
There's something wrong with your logic. What do you mean by Or wdColorBlue Then? This won't work as intended...
If you mean wrd.Font.Color <> wdColorBlue: The font color can't be both black and blue at the same time, so wrd.Font.Color <> wdColorBlack Or wrd.Font.Color <> wdColorBlue will always be true! Therefore the contents of your inner If construct will always execute.
If you mean wrd.Font.Color = wdColorBlue: When the font is blue, then it is necessarily not black, so the wrd.Font.Color <> wdColorBlack condition is redundant and superfluous.
I don't know whether this addresses your problem... I'm not entirely sure what you mean by "it messes up as it counts paragraph marks".