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

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...

Related

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.

VBA Word: Property Revision.Style dosn't work

When I try to change some styles (e.g. textcolor) in a revisions object I get a Run-Time error '5852' (requested object is not available). I've used ActiveDocument.Revisions(i).Style ... Other properties are available (author, creator, type, ...). Btw: I really want change the style from the revision (not the ordinary text). Tested in Word 2010 & 2016
edit: a bit more detailed:
I try to change the color of the revisions that is displayed. Word sets it automically by default. But you can't choose which color Word assigns to reviewers (See this link)
Unfortunately this is exactly what I want to do. So I tried it with VBA and actually there is the property style available for the revision object, but I get an error 5852 in line with ActiveDocument.Revisions(i).Style
Sub test()
i = 1
While i <= ActiveDocument.Revisions.Count
Debug.Print "Revision " & i & " Author: " & ActiveDocument.Revisions(i).Author 'works
Debug.Print "Revision " & i & " Creator: " & ActiveDocument.Revisions(i).Creator 'works
Debug.Print "Revision " & i & " Date: " & ActiveDocument.Revisions(i).Date 'works
Debug.Print "Revision " & i & " FormatDescription: " & ActiveDocument.Revisions(i).FormatDescription 'works...
Debug.Print "Revision " & i & " Range: " & ActiveDocument.Revisions(i).Range 'work
Debug.Print "Revision " & i & " Style: " & ActiveDocument.Revisions(i).Style 'error 5852
Debug.Print "Revision " & i & " Type: " & ActiveDocument.Revisions(i).Type 'works
i = i + 1
Wend
End Sub
Does anyone know why this error occurs?
As you say, it's not possible to set the color for revisions per author, explicitly. It simply is not possible.
I believe that Revisions.Style is not for changing how a revision looks (color or anything else). I believe it's meant to return Style information, such as the name of the style and the various properties (analog to Range.Style). The error is because Word hasn't recorded such information, probably because it doesn't recognize the related style types...
There are two related(?) Revision.Type enums: wdRevisionStyle and wdRevisionStyleDefinition. In a quick test - formatting using a style, creating a style and changing a style definition - I was not able to return either of these revision types. But according to the Language Reference they mean:
wdRevisionStyle 8 Style changed.
wdRevisionStyleDefinition 13 Style definition changed.
In my tests, the type of revision returned for applying a style is wdRevisionParagraphProperty and changing a style definition is not recorded as a Revision.
For Revision.Style to return information I believe you'd need to test whether the Revision.Type is either of the above and only then would there be a valid object in Revision.Style.
I'm looking at Word 2010.

Simple Replace function not working with degree symbol

If I try this -
Replace("±1°", "°", vbNullString)
Result is as expected.
However, I'm extracting data from another workbook, so it's stored in a variable. So, when I run -
Replace(ToleranceLabel, "°", vbNullString)
it never works. Then I tried with the 'Chr' function.
Replace(ToleranceLabel, Chr(176), vbNullString)
still didn't work.
I wanted to verify that the text I was getting the unicode symbol for decimal number 176 and not the unicode using the decimal number 186 for degree. I checked the decimal number and I get 176.
I tried different compare methods, vbTextCompare vs vbBinaryCompare. I still cannot get it to replace the text.
Using InStr to see if it can even find the symbol and it cannot find the degree symbol.
It must be something simple. I'm hoping any of you geniuses might be able to help. Thanks in advance.
You need to understand exactly what is in the cell. Click on the cell and run:
Sub WhatIsInThere()
Dim i As Long, msg As String
msg = Len(ActiveCell.Value) & vbCrLf
For i = 1 To Len(ActiveCell.Value)
msg = msg & vbCrLf & i & vbTab & Mid(ActiveCell.Value, i, 1) & vbTab & AscW(Mid(ActiveCell.Value, i, 1))
Next i
MsgBox msg
End Sub
For example:
Then you can decide how to process the cell.

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.

MS Project VBA getting or setting Title of custom task field Text1..Text30

I try to change the title of the task fields Text1 to Text30 in Microsoft Project 2007 using VBA.
Here is what I do manually:
In Gant Chart Task Table click on table header and add a column. In the popup I can select which task property to add, in my case “Text1” and I can enter a title, for example “my text1”.
But I don’t care about the table. I want to give the title to the text field.
I want to export Text1 to Text30 to an XML file and like to export the title of the field as well, so I need to get the title and I like to set it, because even if it isn’t used in a table it shallbe exported.
Here is what I wrote just for testing:
Private Sub setfieldtitletryout()
Dim i As Integer
Dim c As Long
For i = 1 To 30
c = FieldNameToFieldConstant("Text" & i, pjTask)
Debug.Print "Text" & i; " has constant " & c
Debug.Print " Name of Text" & i; " is " & FieldConstantToFieldName(c) ' well what a surprise...
SetFieldTitle(c, ListOfNames(i)) ' Oviously doesn't work, because the function doesn't exist :-(
Debug.Print " Title of Text" & i; " is " & FieldConstantToFieldTitle(c) ' unfortunately doen't exist too
Next
End Sub
Here is what I checked but did not ready help me…
http://msdn.microsoft.com/en-us/library/bb221504(office.12).aspx
http://msdn.microsoft.com/en-us/library/bb221254(office.12).aspx
I’d be glad to get this fixed!
Thanks in advance for helping out!
Cheers
B
Well I did it :-)
Private Sub setfieldtitletryout()
Dim i As Integer
Dim c As Long
For i = 1 To 5
c = FieldNameToFieldConstant("Text" & i, pjTask) ' get constant of custom field by name
Debug.Print i & ". Rename title of Text" & i
Debug.Print " Name of Text" & i; " is '" & FieldConstantToFieldName(c) & "'"
CustomFieldRename FieldID:=c, NewName:="Titel of Text " & i 'Rename/set custom field title
Debug.Print " Title of Text" & i; " is '" & CustomFieldGetName(c) & "'" ' get title of custom field
Next
End Sub
http://msdn.microsoft.com/en-us/library/ms453877(v=office.12).aspx
Help on CustomFieldRename
Help on CustomFieldGetName