split a text into several lines (inside a cell) in Excel using VBA - vba

I'm using Excel to generate a summery report for my data. I want each summery to be displayed in a single cell. I used VBA and I got something like this:
I want to be able to display the data like this:
All the lines should start with "Increase" or "Decrease". How can I do it in VBA? (I have many cells like the one in this example) how to go over a text inside a specific cell and add a new line after each of these words?

If you are trying to fix the macro so it formats the lines correctly in future then you you need to add in a line feed (I use CrLf myself but Excel, for cells, only cares about the Line Feed) by concatenating the elements with vbLf.
My thanks to #retailcoder for pointing out that vbNewLine == vbCrLf, so you can use whichever makes more sense to you.
so something like Range.Value = "line 1" & vbcrlf & "line 2" & vbcrlf & "line 3" etc:
Range.Value = _
"line 1" & vbcrlf & _
"line 2" & vbcrlf & _
"line 3"
or, personally, I prefer to construct the text through a loop or using Join():
Range.Value = Join(Array( _
"Line 1", _
"Line 2", _
"Line 3"), vbCrLf)
For it to actually display on new lines, you need to double check that Word Wrap is on (Excel will set it on automatically but just in case it has been overridden by something else) using Range.WrapText = True
However, I realise an interpretation is that you just want to quickly fix what is already on the sheet. If this is the case then just manually do a Find and Replace of the word "Increase" or "Decrease" with Char(10)Increase or Char(10)Decrease respectively, where Char(10) is what you can get by pressing Alt+Numpad 0010, or by pasting in the value of the result from the formula =CHAR(10). Then remove the first character using a formula.

Related

Find and Replace every instances of string with Wildcards

I would like to find and replace a certain pattern in word using VBA. More specifically I would like to find every instance of "Table" followed by a whitespace followed by one or more digits followed by another whitespace and replace it with "Table", the same number, a period and a tab. I tried using the Find and Replace function of VBA with the "MatchWildcard" property set to true. Finding the pattern has been no problem, however I can't figure out how to replace the text, so that the number stays the same. My idea was to use the same wildcard in the replacement string, but in this case it just spells out the wildcard as text. Therefore my question is whether there is any way to use the matched value in the replacement string.
toFind = "Table [1-9]# " & vbTab
Dim replacementStr As String
replacementString = "Table [1-9]#." & vbTab
myRange.Find.Execute FindText:=toFind, replaceWith:=replacementStr, _
Replace:=wdReplaceAll, MatchWildcards:=True
Should produce: "Table 1 " -> "Table 1. "
Does produce: "Table 1 " -> "Table [1-9]#. "
For further detail on using wildcards see: https://wordmvp.com/FAQs/General/UsingWildcards.htm
toFind = "(Table [1-9])# " & vbTab
Dim replacementStr As String
replacementStr = "\1." & vbTab
myRange.Find.Execute FindText:=toFind, replaceWith:=replacementStr, _
Replace:=wdReplaceAll, MatchWildcards:=True

How to count how many tabs are in a selection using Macro for formatting tables

I have to format a large document for a file that has been created from a PDF which is editable, so I know all the text is there.
The document is a series of tables. In Word the tables look pretty OK, but in some cases where there should be various cells there is just 1 and tabs have been used to align the text. So, it looks good, but if any of the text gets changed then the formatting will get messed up. I would like to have a macro that looks for cells with a tab, selects the cell, counts the number of tabs, divides the cell into the right number of cells and puts the text into the right cell. For example, a cell that contains "text 1 [tab]text 2[tab]text 3" would become 3 cells "text 1", "text 2" and "text 3".
I thought Word would be able to convert the text to a table, but when the text is already in a table it doesn't work.
If anyone has any suggestions as to how I might achieve this, then they would be much appreciated!
My main issue is not knowing how to count how many tabs are in a selection.
This function will return the number of Tabs in the given string.
Function CountTabs() As Integer
Dim Txt As String
Txt = "This is" & vbTab & "a test" & vbTab & "to count Tabs"
CountTabs = Len(Txt) - Len(Replace(Txt, vbTab, ""))
End Function
The tab character - Chr(9) - is replace with nothing and the number of tabs is the difference in character count before and after the replacement. Here is an implementation of the idea in a snippet.
Private Sub Snippet()
Dim Txt As String
Dim Count As Integer
Txt = "This is" & vbTab & "a test" & vbTab & "to count Tabs"
Count = Len(Txt) - Len(Replace(Txt, vbTab, ""))
MsgBox "There are " & Count & " tabs."
End Sub
Of course, how you get the text for the variable Txt is another story and, in the context of this forum, another question. Prophylactically, I advise against using the Selection object, however. Try to use the Range object instead.

Run-time error VBA upon changing ":" to ";"

Im trying to dynamically add a formula in an Excel sheet using VBA. Something really odd happens. When dynamically creating a formula by using "&" to link together the various components of a string, its gives a Run-time error '1004': Application-defined or object defined error.
This is working (but produces the wrong formula):
Worksheets("Sheet1").Cells(row, 7).Value = "=BDP(f" & row & ":Security Name)"
This is not working (produces the above mentioned error):
Worksheets("Sheet1").Cells(row, 7).Value = "=BDP(f" & row & ";Security Name)"
Note that the ONLY difference is the ":" in front of Security Name became a ";".
Any idea why this is producing this error?
Also, "Security Name" should also be between quotation marks, but when I double up the quotation marks, or use & Chr(34) I get the same error again.
What I am looking for is a formula to be added to the cell which looks like this =BDP(F4:"Security Name")
Your help is appreciated!
If you want a ; in the actual formula you need to use a , in the String you are using.
Also If you write this "" inside the string it will result in this in your string "
So this in you VBA:
.Formula = "=BDP(f" & Row & ",""Security Name"")"
will result in this in you actual cell:
=BDP(F5;"Security Name") (For me the Row was 5)
(You also can set the .Value property instead, but since you´re setting a formula i´d suggest using the .Formula)
Edit:
The method I used, mentioned in the comments:
Sub test()
BBCode = "XS0357495513 Corp"
Sheets(1).Range("A1").Formula = "=BDP(""" & BBCode & """,""Security Name"")"
'Range("A1") is like Cells(1, 1)
End Sub

vbmsgBox prompt is a mix of RTL(Persian) and LTR(English) but text is displayed in wrong order

I am designing a vba userform for excel 2013, in which I use English and Persian text, the problem is when I use a mix of both languages in a msgBox the bits of text come out in the wrong order, the number is supposed to be displayed at the end. here is the code:
Private Sub CommandButton1_Click()
MsgBox "نام" & " - " & "نام" & " - " & "VF" & " - " & 52 & " ." _
, 1 + 1048576 + 524288, "نام برگه"
End Sub
The parts in double quotes and the number are supposed to come from listBoxes.(I just replaced them here with examples, the code behaves the same)
I tried spacing the bits out(works in windows), rearranging the bits and changing msgBox's alignment and reading order, but the result was the same. How to fix this thing?
Could you put all the persian into a string. Have the message box output the string and then have the message box output the numbers?
So it would be something like
aString = ListBox1.value & "-" & listbox2.Value ....
msgbox aString & 52 etc...

Use a cell value (text) as a part of a formula in Excel VBA

I have a problem while doing a macro in Excel VBA which looks simple but I was not able to find an answer.
What I want is to change a formula depending on a value of a concrete cell; the cell is situated in C7 and can have the text OR or the text AND. The part of the formula is (being CritEUs and CritSKUs String variables):
If CritEUs = "NO" (OR/AND) CritSKUs = "NO" Then .... (whatever)
So I want to change the OR/AND depending on the value in C7, I tried to use INDIRECT but I think it works only with numbers, and also the following (being W the Worksheet variable):
Dim Pattern As String
Pattern = W.Range("C7").Value
If CritEUs = "NO" " & Pattern & " CritSKUs = "NO" Then
But the Excel don't accept me this option.
Could it be that this is not possible?
I would really appreciate any help!
I'd look to handle this in another if statement and then nest the next if statement within like so:
Sub Example()
Dim Pattern As String
Pattern = W.Range("C7").Value
If Pattern = "AND" Then
If CritEUs = "NO" And CritSKUs = "NO" Then
'Do Something'
End If
ElseIf Pattern = "OR" Then
If CritEUs = "NO" Or CritSKUs = "NO" Then
'Do Something'
End If
End If
End Sub
Even if I strongly prefer Gareth's solution, there is a trick for doing what you want (i.e. for evaluating the condition) through the usage of the Application.Evaluate() method. It would be:
If Application.Evaluate(Pattern & "(" & Chr(34) & CritEUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & "," & Chr(34) & CritSKUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & ")") Then
... where the string being an expression such as =AND(whatever = "NO", whateverelse = "NO") or =OR(whatever = "NO", whateverelse = "NO") (depending on the value of the variable Pattern) that can be evaluated by the MS Excel application no matter what the system language is.
But as I said, I would personally prefer a nested if block as Gareth suggested because it's clearer what you are doing and it cannot crash if the user inserts an invalid logic operator or makes just a spelling mistake; you should consider this option if you don't want / cannot slightly re-design your code.
FORMULA EXPLANATION - required from the asker
The Evaluate() is a method of the Application object, which means of the object MS Excel. This method is very straightforward:
input: string
output: evaluation of the string
It is in fact used to "evaluate" a string inserted by the user exactly as it does when you type a formula into a cell. If you type into a cell "=3+4", you are basically typing Application.Evaluate("3+4"). This will return you 7, because it's the result of the string evaluation you provided.
This built-in is very very powerful, because it uses a very consolidated system (the one of MS Excel) to parse and evaluate any string that Excel can evaluate. Moreover, the evaluation is always in English (you can use the English function IF but not the Italian SE, nor the German WENN or the French SI because the method evaluates as if your Excel was in English to be system independent.
On the other hand, the Chr(34) is just returning the character ". This character is hard to use in VBA because it's usually need to separate strings (e.g. a = "first" & "second". However, you need this character inside the string to be evaluated so I'm just calling it with Chr(34) to avoid confusion of the compiler.
SUMMARY:
The string is being built up like this:
Pattern & "(" & Chr(34) & CritEUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & "," & Chr(34) & CritSKUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & ")"
Being...
Pattern = AND or OR
Chr(34) = "
... the string that we are building will be of this kind (just a possible outcome):
"AND("NO"="NO","YES"="NO")"
So, once we have built-up this string, we pass it into the Evaluate method: it's like if we were writing =AND("NO"="NO","YES"="NO") into an Excel cell. What would the outcome be? Clearly it depends on your variable, but in this case it would be FALSE, so the If - Then block will not be entered because the return value is false. Otherwise, it would be entered.
This is not a "wrong" method, but as I was saying it has only two possible downsides:
1) It needs data validation, because if you pass crap into the variable Pattern the Evaluate method will fail; in Gareth's solution, instead, only AND and OR will be evaluated, otherwise the code will skip --> more stability;
2) It's not 100% intuitive: while Gareth's solution could be explained to a 10 year old child (because it's very very straight-forward to understand), this one needs (as we just did) a deeper analysis to understand properly what it does. I.E.: you need one line of code to write it, but you/someone else that will have to work on it in the future will need 5-10 minutes and a cup of coffee to understand what the statement wants to check.