This project has moved. For the latest updates, please go here.

Excel: Names.Add Method

Apr 29, 2016 at 2:38 PM
Edited Apr 29, 2016 at 2:41 PM
Hi Sebastian,

as mentioned in the issue section some time ago there seems to be an issue with the "names.add" method in the international context.

In VBA I can simply write
Sub example()
    ActiveWorkbook.Names.Add Name:="name1", RefersTo:="=Offset($A$1,0,0,10,1)"
End Sub
In my german Office installation the formula is automatically converted into the german formule, i.e. adding a name "name1" with formula "=BEREICH.VERSCHIEBEN(Tabelle2!$A$1;0;0;10;1)"

This does not work with NetOffice:
[TestMethod]
        public void AddNameEnglish()
        {
            NetOffice.ExcelApi.Application app = new NetOffice.ExcelApi.Application();
            app.Visible = true;
            app.Workbooks.Add();
            app.ActiveWorkbook.Activate();
            app.ActiveWorkbook.Worksheets.Add();

            ((Excel.Worksheet)app.ActiveSheet).Names.Add("name", "=Offset($A$1,0,0,10,1)");

            app.Dispose();            
        }
This throws an exception:
level 1: InnerException {"Ein Aufrufziel hat einen Ausnahmefehler verursacht."} System.Exception {System.Reflection.TargetInvocationException}
level 2: "Die eingegebene Formel enthält einen Fehler. Versuchen Sie eines der folgenden Verfahren, um die Formel zu korrigieren:
• Überprüfen Sie, ob alle Klammern und erforderlichen Argumente vorhanden sind.
• Klicken Sie auf der Registerkarte 'Formeln' auf 'Funktion einfügen' (in der Gruppe 'Funktionsbibliothek'), um Hilfe beim Verwenden einer Funktion zu erhalten.
• Sofern Sie Bezug auf eine andere Arbeitsmappe oder ein anderes Blatt nehmen, vergewissern Sie sich, dass die Angaben richtig sind.
• Sofern Sie keine Formel eingeben, vermeiden Sie Minuszeichen (-) oder Gleichheitszeichen (=). Falls diese Zeichen erforderlich sind, fügen Sie vorher ein einzelnes Anführungszeichen (') ein.
• Um weitere Information zu erhalten, klicken Sie auf 'Hilfe'."

So it looks like NetOffice has a problem in translating the formula properly. I tried the same with the german formula and this works fine:
[TestMethod]
        public void AddNameGerman()
        {
            NetOffice.ExcelApi.Application app = new NetOffice.ExcelApi.Application();
            app.Visible = true;
            app.Workbooks.Add();
            app.ActiveWorkbook.Activate();
            app.ActiveWorkbook.Worksheets.Add();

            ((Excel.Worksheet)app.ActiveSheet).Names.Add("name", "=BEREICH.VERSCHIEBEN($A$1; 0; 0; 10; 1)");

            app.Dispose();
        }
However, I want to use the "auto translation" of the formula as it is available in VBA. The documentation under https://msdn.microsoft.com/en-us/library/office/ff835300.aspx says, that the "RefersTo" parameter should be provided in english ("Describes what the name refers to, in English, using A1-style notation, if the RefersToLocal, RefersToR1C1, and RefersToR1C1Local parameters are not specified.").

So I would highly appreciate if you could look into this. Iam using NetOffice 1.7.3., Win 10 and Excel 2013.

Many thanks and have a nice weekend!

coheedld
Coordinator
May 1, 2016 at 8:20 PM
Das ist ja merkwürdig. Das heisst BEREICH.VERSCHIEBEN funktioniert und Offset nicht - richtig? Office übergibt bei jedem Aufruf immer die ThreadCulture des Aufrufers und die ist per default 1031-En-US(änderbar unter Settings.ThreadCulture) was auch in meinen eigenen Projekten bisher immer bestens funktioniert hat. Ich muss mal nachfragen bist du in einem IIS Szenario oder sonst irgendwie speziell? (Für mich hat das bisher immer bestens funktioniert bis auf Addins/Exe's die Code aus extra erstellten Treads aufrufen, dann versagt die Länderkennung bisweilen)

(NetOffice translated da garnichts, das macht Office von Hause aus. Office glaubt an dem Punkt es ist in deutsch, warum das so ist würde ich auch gerne wissen weils eben auch eine wichtige infrastrukturelle Frage für NetOffice ist.)

*Sebastian
(Skype:public.sebastian)
May 1, 2016 at 8:46 PM
Edited May 1, 2016 at 8:47 PM
Korrekt, wenn ich die Formel mit "BEREICH-VERSCHIEBEN" eingebe wird der Name korrekt erzeugt. Mit "OFFSET" und der englischen Syntax ("," anstatt ";") funktioniert das nicht. In VBA gebe ich die Formel immer in Englisch an und Office übersetzt diese dann selbstständig in die entsprechende Sprache der Installation.

Wenn ich in der Methode, die den Namen setzt, die Location abrufe, bekomme ich 1031 geliefert
xlsApp.LanguageSettings.LanguageID(NetOffice.OfficeApi.Enums.MsoAppLanguageID.msoLanguageIDUI)
In einem "speziellen Szenario" bin ich meines Erachtens nicht.

Kannst du dir das mal anschauen?

Vielen Dank und beste Grüße!

coheedld
Coordinator
May 1, 2016 at 9:29 PM
Huch, kleines Typo Edit, nicht Office übergibt bei jedem Aufruf die ThreadCulture sondern natürlich NetOffice übergibt die diese an Office. (genauer gesagt übergibt Netoffice die Kontrolle an COM Interop und das simuliert dann gegenüber Office die gewünschte Lokale.

Das liesse sich an deinem Beispiel wiefolgt ändern.

NetOffice.ExcelApi.Application app = new NetOffice.ExcelApi.Application();
app.Settings.ThreadCulture = new System.Globalization.CultureInfo(1031);

)

Ich muss dich das jetzt nochmal fragen bevor ich anfange das aufwendig nachzustellen. Hast du eine ganz normale Desktop Anwendung laufen in der du das testweise auziehst? Kein Remote-Desktop, kein IIS, kein Quirks? Läuft dein Code in einem Office Addin oder normal als .exe? Das ist wichtig weil sich COM Interop jeweils anders verhält wenn der Origin Thread ein Single Thread oder vielleicht ein COM STA Thread ist(was bei Addins der Fall ist), im letzteren Fall funktionieren bestimmte Features von .Net nicht. Lange Rede kurzer Sinn, je genauer du dein Szenario beschreiben kannst umso besser. Ich such mich sonst tot nach Sachen von denen du wahrscheinlich noch nie was gehört hast. Das hilft dir nicht und das hilft mir nicht. (Du hast das Problem gut beschrieben und dir da (vergleichbar) viel Mühe gemacht, schön :) ich bin voll dabei aber jetzt brauch ich Fakten und das nicht im Support-Sprech- einige Fragen mögen dir nicht einleuchten aber beachte und beantworte diese bitte trotzdem - ich denk mir schon was dabei)


WM_REGARDS
(OffTopic:Wie ist eigentlich die Grosswetterlage gerade so in Deutschand?)
May 2, 2016 at 8:15 AM
Hallo Seabstian,

habe die Testmethode nochmal angpasst und die ThreadCulture explizit gesetzt, es wird aber die gleiche exception geschmissen. Ich habe auch im Programm während der Laufzeit mal die ThreadCulture abgezogen, diese ist korrekterweise "en-US".
[TestMethod]
        public void AddNameEnglish()
        {
            NetOffice.ExcelApi.Application app = new NetOffice.ExcelApi.Application();
            app.Settings.ThreadCulture = new System.Globalization.CultureInfo(1031);
            app.Visible = true;
            app.Workbooks.Add();
            app.ActiveWorkbook.Activate();

            ((Excel.Worksheet)app.ActiveSheet).Names.Add("name", "=Offset(Tabelle1!$A$1,0,0,10,1)");

            app.Dispose();            
        }
Zur Anwendung: Es handelt sich eigentlich nur um eine Klassenbibliothek, die in Office als Addin registriert wird und ausschließlich aus der Office Anwendung heraus über das Ribbon angesteuert wird. Ich kompiliere einfach den Code, der registriert dann das Addin und dann öffne ich die entsprechende Office App und nutze die Funktionalität. Kein remote zeugs, kein Kompatibilitätsmodus o.Ä. Ist die Info hilfreich?

(OffTopic: Großwetterlage nach ein paar kalten und teilweise verschneiten Tagen eigentlich ok: Am Wochenende gabs Sonnenschein und es war schon ein bisschen warm. Nächstes WE soll es ähnlich werden).
May 2, 2016 at 9:44 AM
Update: Mit den Interop Assemblies funktioniert das auch nicht wie in VBA (scheint also kein NetOffice Problem zu sein). Folgender Code wirft die gleiche exception (ungültige Formel):
[TestMethod]
        public void AddNameEnglish3()
        {
            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
            app.Visible = true;
            app.Workbooks.Add();
            app.ActiveWorkbook.Activate();
            app.ActiveWorkbook.Names.Add("tester", "=Offset('Tabelle1'!$A$1,0,0,1,1)");
        }
interessant ist, dass der folgende code einen Namen anlegt (";" anstatt "," in der Formel):
[TestMethod]
        public void AddNameEnglish4()
        {
            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
            app.Visible = true;
            app.Workbooks.Add();
            app.ActiveWorkbook.Activate();
            app.ActiveWorkbook.Names.Add("tester", "=Offset('Tabelle1'!$A$1;0;0;1;1)");
        }
Die angelegte Formel wird allerdings 1:1 übernommen, also als "=Offset(Tabelle1!$A$1;0;0;1;1)" hinterlegt. Aber meine deutsche Office Version kennt natürlich kein "Offset" und daher ist das unbrauchbar.
Coordinator
May 7, 2016 at 12:24 PM
Wenn du AddNameEnglish3() als Netoffice Variante testen lässt, wird dann auch "," in ";" umgewandelt oder scheitert der Aufruf?
May 7, 2016 at 1:19 PM
Der Aufruf scheitert:
[TestMethod]
        public void AddNameEnglish3NetOffice()
        {
            NetOffice.ExcelApi.Application app = new NetOffice.ExcelApi.Application();
            app.Visible = true;
            app.Workbooks.Add();
            app.ActiveWorkbook.Activate();
            app.ActiveWorkbook.Names.Add("tester", "=Offset('Tabelle1'!$A$1,0,0,1,1)");
        }
Exception Message: "Die eingegebene Formel enthält einen Fehler. Versuchen Sie eines der folgenden Verfahren, um die Formel zu korrigieren:

• Überprüfen Sie, ob alle Klammern und erforderlichen Argumente vorhanden sind.
• Klicken Sie auf der Registerkarte 'Formeln' auf 'Funktion einfügen' (in der Gruppe 'Funktionsbibliothek'), um Hilfe beim Verwenden einer Funktion zu erhalten.
• Sofern Sie Bezug auf eine andere Arbeitsmappe oder ein anderes Blatt nehmen, vergewissern Sie sich, dass die Angaben richtig sind.
• Sofern Sie keine Formel eingeben, vermeiden Sie Minuszeichen (-) oder Gleichheitszeichen (=). Falls diese Zeichen erforderlich sind, fügen Sie vorher ein einzelnes Anführungszeichen (') ein.
• Um weitere Information zu erhalten, klicken Sie auf 'Hilfe'."
May 8, 2016 at 7:26 AM
Noch folgende interessante Beobachtung:
[TestMethod]
        public void AddNameEnglish3NetOffice()
        {
            NetOffice.ExcelApi.Application app = new NetOffice.ExcelApi.Application();
            app.Visible = true;
            app.Workbooks.Add();
            app.ActiveWorkbook.Activate();
            ((Excel.Worksheet)app.ActiveWorkbook.ActiveSheet).Cells[1, 1].Value = "=TODAY()";
            //app.ActiveWorkbook.Names.Add(name: "tester", refersTo: "=Offset('Tabelle1'!$A$1,0,0,1,1)");
            app.ActiveWorkbook.Names.Add(name: "tester", refersTo: "=TODAY()");
        }
Hier wird in Zelle A1 des aktuellen Sheets korrekterweise die Formel übersetzt und es wird "=HEUTE()" eingetragen. Im NameManager erhalte ich jedoch einen Namen "tester", der auf "=TODAY()" verweist. Hier wird die Formel nicht übersetzt und daher funktioniert sie auch nicht.