Mac Keybindings with German umlauts - vba

I know how to bind a key to a sub in VBA for Mac (Word 2016 etc.). But I can't find a way to do so with German umlauts. I already created some code to bind all 255 variations of wdKey to code, but that didn't get me a solution either. The keys ä, ö, ü on my keyboard never fire any event.
I'd be happy for any advice.

I do not think it is possible.
Some notes:
It looks as if you asked a similar question here in 2012, and the suggestion in there that the problem is that these keys cannot be assigned in Word, only in Mac OS, seems still to be correct. However, that seems to mean that you can only assign a key combination that Mac OS allows you to assign, to an existing Word menu item. So you can use that mechanism to assign ctrl-ö to "Advanced Symbol..." but you cannot use that mechanism to assign ctrl-ö to a Word internal command name and I do not think you can assign ö, on its own, to anything.
In Windows Word, I was able to assign alt-ö, alt-ä and alt-ü to "InsertSymbol" in Word, but the keystrokes Word actually assigned this comand to were the Alt-shifted wdKeyBackSingleQuote, wdKeySingleQuote, and wdKeySemiColon.
Attempting to use the same key assignments in Mac VBA did not work.
On my (UK) keyboard, the actual keys used for ö, ä and ü are SemiColon, Comma, and LeftSquareBracket. Even on the US English keyboard, I think they are SemiColon, SingleQuote, and LeftSquareBracket, so it is not obvious why Word assigns those particular codes. I think you would probably have to understand how DOS and Widnows and Word deal with keyboard scan codes to make sense of it, and on Mac it will of course be different.
For anyone wishing to explore further, you can use VBA to reassign a key without using BuildKeyCode, like this:
Dim i As Integer
i = 1022
KeyBindings.Add KeyCode:=i, _
KeyCategory:=wdKeyCategoryCommand, _
Command:="InsertSymbol"
Some values of i cause an "Invalid Parameter" command, and others a 5346 "Word cannot change the function of the specified key". Most of these values of i probably just represent a "base keystroke" such as "A", eithe ron its own or combined with one or more shifts such as Shift, Alt, etc., but without exploring every single possibile value of i that does not raise an error it is difficult to be certain that there are no other possibilities.

Related

VIM equivalent of IntelliJ's expand/shrink selection?

How would one achieve the same result. I believe the keybinding for macOS Intellij is op+up/down and on windows it is alt+w/d.
Essentially the function highlights the current word, then, with successive presses, expands out to the full string/line/area in-between parenthesis/further out to the next set of parenthesis. Very useful for developing in LISP.
The closest I've gotten is this: https://vi.stackexchange.com/a/19028
Try this plug in: https://github.com/terryma/vim-expand-region
It expands selections based on Vim’s text objects.
Well this may seem comfortable but does not correspondent with the internal logic of vim itself.
See, in vim everything you enter is like a sentence. va{ for example: there is a verb v -> visually select and an object (or movement) { -> paragraph. In this case there is also a modifier a around. You can exchange stuff in this sentence and it will still work vaw, dil, cB and so on. The power of vim is greatly based on that concept.
Of course you can write a function that does vaw first, then S-v and lastly va{ but that will only work with visual selection. It will not work with c or d or anything. So I will recommend to get used to use different keys for different actions.
The visual selection is mostly not needed anyway. Change a paragraph? directly use ca} and so on.
I have found that VI/VA + WOBO (as many times as you need to expand) works similarly. Not as fast but its the same concept and you can even expand/shrink asymmetrically based on your WO's and BO's (Or OW's and OB's depending on how you look at it)

How to determine Thousands Separator using Format in VBA

I would like to determine the Thousand Separator used while running a VBA Code on a target machine without resolving to calling system built-in functions such as (Separator = Application.ThousandsSeparator).
I am using the following simple code using 'Format':
ThousandSeparator = Mid(Format(1000, "#,#"), 2, 1)
The above seems to work fine, and would like to confirm if this is a safe method of doing it without resorting to system calls.
I would expect the result to be a single char string in the form of , or . or ' or a Space as applicable to the locale on the machine.
Please note that I want to only use a language statement such as Format or similar (no sys calls). Also this relates to Thousands Separator not Decimal Separator. This article Using VBA to detect which decimal sign the computer is using does not help or answer my question. Thanks
Thanks in advance.
The strict answer to whether it is safe to use Format to get the thousands separator is No.
E.g. on Windows, it is possible to enter up to three characters into the Thousands Separator field in the regional settings in the control panel.
Suppose you enter asd and click OK.
If you now call Format(1000, "#,#") it will give you 1a000. That is only the first letter of your thousands separator. You have failed to retrieve it correctly.
Reading the registry:
? CreateObject("WScript.Shell").RegRead("HKCU\Control Panel\International\sThousand")
you get back asd in full.
To be fair, the Excel international properties do not seem to be of much help either. Application.International(xlThousandsSeparator) in this situation will return the separator originally defined in your computer's locale, not the value you've overridden it to.
Having that said, the practical answer is Yes, because it would appear (and if you happen to know for sure, please post an answer here) that there is no culture with multi-char thousand separator (even in China where scary things like 1億2345万6789 or 1億2345萬6789 exist, they happen to be represented with just one UTF-16 character), and you probably are happy to ignore the people who decided to play with their locale settings in that fashion.

"base" Keyword in LibreOffice Basic

I'm writing a macro for LibreOffice Calc in Basic in VBA compatibility mode. It complains when I use this line:
Const BASE = 3
BASIC syntax error.
Symbol expected.
and the syntax coloring seems to indicate that "BASE" is a keyword or reserved word. Other consts in the macro are accepted without issue. Also, this line is accepted in VBA in Excel.
I will change the name in order to avoid this problem, however I am unable to locate any documentation that references this as being any kind of reserved word. I assume it either has something to do with number bases or with the name of LO's database. However, words like "WRITER" and "CALC" don't act the same way - they seem to be accepted as names for constants. Note that my use of this word is not related to the database anyway.
Also, unfortunately, LO Basic doesn't seem to have an immediate mode (REPL) so I am unable to easily play with this word to determine what it's used for.
Can you point me toward some documentation for the keyword BASE?
Those are some good guesses, but incorrect as it turns out. The word is used as follows:
Option Base 1
It can be either 0 or 1 to denote which index refers to the first element of an array, as documented at https://wiki.openoffice.org/wiki/G11ntest/Documentation/BASIC_Guide/Arrays.
To discover this, I looked through the LibreOffice source code. The file /basic/source/inc/parser.hxx was helpful. This is the closest approximation of a list of keywords available, judging from this post.
Apparently, this statement was adopted from VBA: https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-base-statement

Add spaces between words in spaceless string

I'm on OS X, and in objective-c I'm trying to convert
for example,
"Bobateagreenapple"
into
"Bob ate a green apple"
Is there any way to do this efficiently? Would something involving a spell checker work?
EDIT: Just some extra information:
I'm attempting to build something that takes some misformatted text (for example, text copy pasted from old pdfs that end up without spaces, especially from internet archives like JSTOR). Since the misformatted text is probably going to be long... well, I'm just trying to figure out whether this is feasibly possible before I actually attempt to actually write system only to find out it takes 2 hours to fix a paragraph of text.
One possibility, which I will describe this in a non-OS specific manner, is to perform a search through all the possible words that make up the collection of letters.
Basically you chop off the first letter of your letter collection and add it to the current word you are forming. If it makes a word (eg dictionary lookup) then add it to the current sentence. If you manage to use up all the letters in your collection and form words out of all of them, then you have a full sentence. But, you don't have to stop here. Instead, you keep running, and eventually you will produce all possible sentences.
Pseudo-code would look something like this:
FindWords(vector<Sentence> sentences, Sentence s, Word w, Letters l)
{
if (l.empty() and w.empty())
add s to sentences;
return;
if (l.empty())
return;
add first letter from l to w;
if w in dictionary
{
add w to s;
FindWords(sentences, s, empty word, l)
remove w from s
}
FindWords(sentences, s, w, l)
put last letter from w back onto l
}
There are, of course, a number of optimizations you could perform to make it go fast. For instance checking if the word is the stem of any word in the dictionary. But, this is the basic approach that will give you all possible sentences.
Solving this problem is much harder than anything you'll find in a framework. Notice that even in your example, there are other "solutions": "Bob a tea green apple," for one.
A very naive (and not very functional) approach might be to use a spell-checker to try to isolate one "real word" at a time in the string; of course, in this example, that would only work because "Bob" happens to be an English word.
This is not to say that there is no way to accomplish what you want, but the way you phrase this question indicates to me that it might be a lot more complicated than what you're expecting. Maybe someone can give you an acceptable solution, but I bet they'll need to know a lot more about what exactly you're trying to do.
Edit: in response to your edit, it would probably take less effort to run some kind of OCR tool on a PDF and correct its output than it would just to correct what this system might give you, let alone program it
I implemented a solution, the code is avaible on code project:
http://www.codeproject.com/Tips/704003/How-to-add-spaces-between-spaceless-strings
My idea was to prioritize results that use up most of the characters (preferable all of them) then favor the ones with the longest words, because 2,3 or 4 character long words can often come up by chance from leftout characters. Most of the times this provides the correct solution.
To find all possible permutations I used recursion. The code is quite fast even with big dictionaries (tested with 50 000 words).

Asc(Chr(254)) returns 116 in .Net 1.1 when language is Hungarian

I set the culture to Hungarian language, and Chr() seems to be broken.
System.Threading.Thread.CurrentThread.CurrentCulture = "hu-US"
System.Threading.Thread.CurrentThread.CurrentUICulture = "hu-US"
Chr(254)
This returns "ţ" when it should be "þ"
However, Asc("ţ") returns 116.
This: Asc(Chr(254)) returns 116.
Why would Asc() and Chr() be different?
I checked and the 'wide' functions do work correctly: ascw(chrw(254)) = 254
Chr(254) interprets the argument in a system dependent way, by looking at the System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage property. See the MSDN article about Chr. You can check whether that value is what you expect. "hu-US" (the hungarian locale as used in the US) might do something strange there.
As a side-note, Asc() has no promise about the used codepage in its current documentation (it was there until 3.0).
Generally I would stick to the unicode variants (ending on -W) if at all possible or use the Encoding class to explicitly specify the conversions.
My best guess is that your Windows tries to represent Chr(254)="ţ" as a combined letter, where the first letter is Chr(116)="t" and the second ("¸" or something like that) cannot be returned because Chr() only returns one letter.
Unicode text should not be handled character-by-character.
It sounds like you need to set the code page for the current thread -- the current culture shouldn't have any effect on Asc and Chr.
Both the Chr docs and the Asc docs have this line:
The returned character depends on the code page for the current thread, which is contained in the ANSICodePage property of the TextInfo class. TextInfo.ANSICodePage can be obtained by specifying System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage.
I have seen several problems in VBA on the Mac where characters over 127 and some control characters are not treated properly.
This includes paragraph marks (especially in text copied from the internet or scanned), "¥", and "Ω".
They cannot always be searched for, cannot be used in file names - though they could in the past, and when tested, come up as another ascii number. I have had to write algorithms to change these when files open, as they often look like they are the right character, but then crash some of my macros when they act strangely. The character will look and act right when I save the file, but may be changed when it is reopened.
I will eventually try to switch to unicode, but I am not sure if that will help this issue.
This may not be the issue that you are observing, but I would not rule out isolated problems with certain characters like this. I have sent notes to MS about this in the past but have received no joy.
If you cannot find another solution and the character looks correct when you type it in, then I recommend using a macro snippet like the one below, which I run when updating tables. You of course have to setup theRange as the area you are looking at. A whole file can take a while.
For aChar = 1 To theRange.Characters.count
theRange.Characters(aChar).Select
If Asc(Selection.Text) = 95 And Selection.Text <> "_" Then Selection.TypeText "Ω"
Next aChar