Laden...

[gelöst] C# zu VBA

Erstellt von Larsen vor 17 Jahren Letzter Beitrag vor 16 Jahren 9.837 Views
L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren
[gelöst] C# zu VBA

Hallo Forum,

ich habe ein Problem mit dem Rückgabetyp einer Funktion aus meiner C# DLL, die ich in anderen Programmen nutzen will.

Rückgabe aus C# DLL:

string [] Test();

in VBA versuche ich folgendes

dim A() as String

A=Test -> Fehlermeldung zur Laufzeit.

Wie bekomme ich ein String Array aus der DLL zurück?
Wo kann ich am besten nachlesen wie Rückgaben aus .NET mit bestimmten Datentypen funktionieren?

Gruß
Larsen

Sorry, ist im falschen Forums Bereich gelandet, ich weiß jetzt aber nicht ob und wie ich das nach " Basistechnologien und allgemeine .NET-Klassen " bekomme.

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

6.862 Beiträge seit 2003
vor 17 Jahren

User können selber keine Themen verschieben, das machen die Moderatoren. Habs aber nach Office geschoben - denke da passt VBA besser hin.

Baka wa shinanakya naoranai.

Mein XING Profil.

3.728 Beiträge seit 2005
vor 17 Jahren
Fehlermeldung

Was für eine Ausnahme kriegst Du denn (COMException, ...)?

Wie lautet der genaue Fehlertext der Ausnahme?

S
1.047 Beiträge seit 2005
vor 17 Jahren

edit: sorry war unsinn o.O

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hi Rainbird,
ich habe folgende Fehlermeldung:

_Fehler beim Kompilieren:

Funktion oder Schnittstelle kann nur eingeschränkt verwendet werden oder verwendet einen Automatisierungstyp, der in Visual Basisc nicht unterstützt wird._

Was ich übergeben will ist ein string Array.
Muß ich das verwerfen?

Gruß
Larsen

PS: Die Fehlermeldung kommt doch direkt beim Start des Programms nicht erst zur Laufzeit.

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

1.274 Beiträge seit 2005
vor 17 Jahren

Versuche mal aus dem String Array ein Objekt Array zu machen.

"Das Problem kennen ist wichtiger, als die Lösung zu finden, denn die genaue Darstellung des Problems führt automatisch zur richtigen Lösung." Albert Einstein

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hi,

hab ich versucht, die Fehlermeldung aber bleibt 😦

Was einwandfrei funktioniert, ist ein einzelnen String zu übergeben.
Nur das Array macht Zicken.

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

L
17 Beiträge seit 2006
vor 17 Jahren

hi

in vb beispielsweise vba macht man das so

dim a as string

aber nie dim a() as string

bin leider schon zu lang raus aber dlls musst du erstmal einbinden

z.b. so ist nur ein beispiel für eine ms dll datei

Private Declare Function ChangeDisplaySettings Lib _
"user32" Alias "ChangeDisplaySettingsA" _
(lpDevMode As Any, ByVal dwFlags As Long) As Long

in vba muss man das aber als public machen so wie ich das noch weiß aber das findet man schnell raus wenn vba meckern tut ^^^

gruss Diablo2k

S
1.047 Beiträge seit 2005
vor 17 Jahren

Original von LonelyWolf
aber nie dim a() as string

öhm, er möchte ein string-array, und in vba wird genau über solch eine zeile ein string-array deklariert

das () zeigt dabei an des es ein array ist

3.728 Beiträge seit 2005
vor 17 Jahren
MarshalAs

Versuchs mal so:


using System.Runtime.InteropServices;

...

[MarshalAs(UnmanagedType.ByValArray)]
public string[] Test()
{
    ...
}

http://msdn2.microsoft.com/en-us/library/ms172514.aspx

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hi,

so dieht die Function aus:


        [MarshalAs(UnmanagedType.ByValArray)]
        public string[] Test()
        {
            Dictionary<string, Dictionary<string, string>>.KeyCollection K;
            K = DictOutput.Keys;
            string  [] array = new string  [K.Count ];

            K.CopyTo(array,0);
            
            return array;
        }

dann bekomme ich folgende Fehlermeldung:
_
Das MarshalAs-Attribut ist für diesen Deklarationstyp nicht gültig. Es ist nur für field, param, return-Deklarationen gültig._

Warscheinlich ist das der richtige Weg, aber irgendwas läuft noch falsch.

Ich hätte nicht gedacht, dass das so schwieig wird ein string Array zu übergeben.

Hat noch jemand eine Idee?
Weil ich zur Zeit keine habe bin ich für jeden Tip dankbar.

Gruß
Larsen

Ich habe in der Zwischenzeit folgendes ausprobiert:


 public interface IDataInfo
    {
        ....    
        [DispId(6)]
        [return: MarshalAs(UnmanagedType.LPArray)] string [] Test();
    }

.....
 public  string [] Test()
        {
            Dictionary<string, Dictionary<string, string>>.KeyCollection K;
            K = DictOutput.Keys;
            
            string  [] array = new string  [K.Count ];

            K.CopyTo(array,0);
            
            return array;
        }
......

führt aber auch nicht zum Erfolg 😦

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

3.728 Beiträge seit 2005
vor 17 Jahren
Collection

Kannst Du keine Collection verwenden?

Arrays sind in VBA eh blöd zu handhaben.

Falls ich das mit den Arrays trotzdem noch rauskriege, poste ich es hier.

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hi,

wenn Collections gehen, OK, ich bin nicht auf StringArray festgelegt. Ich werd mich mal einlesen und das ausprobieren.

Ich habe StringArray gewählt, da ich diese Daten auch an andere Programme weitergeben muß und ich dachte, mit einem String Array bewege ich mich auf einem relativ gesicherten Format.

Ich probier das mal aus und poste dann wieder...

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hallo,
folgendes habe ich ausprobiert:

public ArrayList Test()
        {
            
            Dictionary<string, Dictionary<string, string>>.KeyCollection K;
            K = DictOutput.Keys;

            ArrayList array = new ArrayList();

            foreach (object  i in K)
            {
                array.Add(i.ToString());
            }

            return array;
        }

in VBA habe ich dann folgenden Code ausprobiert:

Sub Test()
Dim Ar As Collection
Dim O As TestClass.Test

Set O = New TestClass.Test

Set Ar = O.Test --> Fehlermeldung: Typen unverträglich 😦

End Sub

Ich habe mittlerweile eine Schnittstelle implementiert, die mein StringArray über eine Schleife zurückgeben kann(Wert für Wert). Das ist zwar Mist aber es funktioniert erst mal.

Ich habe in C# eine Liste von "strings" und möchte diese möglichst programm übergreifend kompatibel als Rückgabe aus einer Methode weiter verarbeiten.
Funktionieren soll das hinterher mit Excel und Labview.

Falls jemand so etwas schon mal gemacht hat, bitte posten.

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

476 Beiträge seit 2004
vor 17 Jahren

Original von Larsen
Wie bekomme ich ein String Array aus der DLL zurück?

hallo Larsen,

im Prinzip müsste es so gehen wie du deinen Versuch im ersten Posting beschrieben hast. Ich habe ein kleines Beispielprojekt erstellt, mit welchem es auf meinem Rechner einwandfrei funktioniert. Versuch's mal damit. Sollte das auch nicht gehen, könnte es an deiner Entwicklungsumgebung liegen.

-yellow

Selbst ein Weg von tausend Meilen beginnt mit einem Schritt (chinesisches Sprichwort).

Mein Blog: Yellow's Blog auf sqlgut.de

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hi yellow

ich habe das mal ausprobiert und bekomme die gleiche Fehlermeldung wie sonst auch:

Funktion oder Schnittstelle kann nur eingeschränkt verwendet werden oder verwendet einen Automatisierungstyp, der in Visual Basisc nicht unterstützt wird.

Wie hast du das ausprobiert? Mein "Testobjekt" ist meist Excel(leider noch aus Office 97). Verwenden will ich das noch zusätzlich in Labview. Da ich selber aber kein Labview kann, möchte ich das natürlich erst unter Excel ans laufen bringen.

Mir klingt das fast so als würde ich das eigentlich schon richtig machen, aber vielleicht ist meine Excel Version einfach zu alt.
Trotzdem DANKE für das Beispielprojekt.

Ich habe im Moment die Übergabe der string Daten in einer Schnittstelle implementiert, die in einer Schleife alle Daten übergeben kann. Das ist zwar nicht sonderlich elegant aber es funktioniert.

Ich werde aber die Test dll von dir mal unter Labview ausprobieren, mal sehen ob es da geht. Das wäre auf jeden Fall ein Hinweis, das mein Excel zu alt ist. Ich poste dann das Ergebnis.

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

476 Beiträge seit 2004
vor 17 Jahren

hallo Larsen,

also, ich habe das Projekt unter Visual Studio 2003 erstellt, und in Visual Basic 6.0 sowie in Excel 2003 als Verweis eingebunden. Anschließend das Projekt mit Visual Studio 2005 konvertiert und neu kompiliert und wiederum in Excel 2003 und Visual Basic 6.0 eingebunden.

Ich glaube nicht, dass es an der "alten" Excel Version liegt, da sich meines Wissens nach nichts mehr grossartiges in VBA geändert hat. Leider habe ich kein Excel 97 und kann es somit nicht versuchen sondern nur vermuten.

-yellow

Selbst ein Weg von tausend Meilen beginnt mit einem Schritt (chinesisches Sprichwort).

Mein Blog: Yellow's Blog auf sqlgut.de

3.728 Beiträge seit 2005
vor 17 Jahren
Support

Hallo Larsen,

vielleicht hilft Dir folgender KB-Artikel: http://support.microsoft.com/kb/316653/

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hi,
ich habe den Artikel gelesen, ist sehr interessant zu sehen was aus dem Code wird den man da geschrieben hat.
Was mir nicht gelingt, ist das dort beschriebene Problem auf meins zu beziehen.
Das heißt ich kann mir das alles auf Assembler Ebene anschauen, ist bei Yellows Beispiel auch recht nachvollziehbar, aber ich weiß nicht was ich hier ändern könnte um das Problem zu lösen. Der Bezeichner aus dem Artikel taucht bei mir nicht auf und einfach mal drauf los zu ändern ist sicherlich nicht sinnvoll.

Ich habe mittlerweile versucht das Array in Labview einzubinden, aber auch hier funktioniert das nicht wirklich.
Das könnte aber wieder eine andere Baustelle sein, weil ich halt kein Labview Experte bin.

Ich denke, um nicht mit diesem Problem zu verzweifeln, mache ich mit meiner Schleifenlösung weiter. Wenn ich mal wieder mehr Zeit habe gehe ich dann wieder an dieses Problem.

DANKE für euer Anregungen.

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

3.728 Beiträge seit 2005
vor 17 Jahren
Neues Excel

Hast Du die Möglichkeit Deine Assembly in einem neueren Excel einzubinden? Damit könnte man eingrenzen, ob dieses Problem nur speziell bei Excel 97 besteht.

Man kann kostenlos 60-Tage Testversionen von Office Programmen bei Microsoft herunterladen.

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hi,
das kann ich machen, vielleicht kann man dann das Problem eingrenzen!

Ich poste dann das Ergebnis!

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 17 Jahren

Hallo,

tatsächlich, ich habs eben bei einem Kumpel ausprobiert, mit Excel aus Office2003 klappt das ohne Probleme (ich hab Yellows Test dll benutzt).
Schade das wir in der Firma, aus kompatibilitätsgründen 😛, noch mit Office97 arbeiten. Mittlerweile sehe ich hier einige größere Probleme auf uns zukommen.

Also muß ich mich mit der Lösung der Schleifenbearbeitung erst mal zufrieden geben, bis wir auf modernere Office Versionen wechseln. Ärgerlich nur, dass man immer so viel Zeit aufwenden muß um das Problem zu umzingeln.

Vielen DANK an alle die mir geholfen haben !!!!

Bis zum nächsten Problem 😁

Gruß
Larsen

PS: mal ne dumme Frage, kann ich diesen Beitrag irgendwie als gelöst kennzeichnen? Oder wie geht das?

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

P
41 Beiträge seit 2007
vor 16 Jahren
VB 6 Aufruf einer c# dll mit int[]

Hallo,
habe gerade Dein COMWrapper ausprobiert, geht!
Ich möchte einer Funktion einen int[] Array übergaben, das geht dann leider nicht.
Hast Du dafür eventuell auch ein paar Zeilen?

Hier mein Versuch:


[Guid("1A915786-4642-4bc9-8C10-D14955AA0413"), ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IYellowWrapper_1
    {
        /// <summary>
        /// Gibt ein String-Array zurück
        /// </summary>
        [DispId(1)]
        string[] GetArray(int[] ar);
    }

Folgende MarshalAs habe ich schon probiert:


[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_I4)] int[] ar
oder 
[In, MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4 , SizeConst=10)] int[] ar

Geht leider alles nicht, igendeine Idee?

Viele Grüße
Andreas

P
41 Beiträge seit 2007
vor 16 Jahren
vb6 - > c# int[]

habs rausgefunden.

das geht jetzt:

[In, MarshalAs(UnmanagedType.SafeArray,SafeArraySubType=VarEnum.VT_I4)] ref System.Int32[] Groups

VG
Andreas

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 16 Jahren

Hi, prima,
wie genau muß man das jetzt definieren,
kannst du die Funktion und das Interface mal posten?

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!

P
41 Beiträge seit 2007
vor 16 Jahren

Hi Larsen,
hier der Code.
Nur leicht verändert. Sonst gleich dem Beispiel von oben.
Es kommt wohl auf das ref an.

VG Andreas

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace COMWrapper
{
/// <summary>
/// Zusammenfassung für IYellowWrapper.
/// </summary>
[Guid("1A915786-4642-4bc9-8C10-D14955AA0413"), ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IYellowWrapper_1
{
/// <summary>
/// Gibt ein String-Array zurück
/// </summary>
[DispId(1)]
void GetArray([In, MarshalAs(UnmanagedType.I2)] System.Int16 data,
[In, MarshalAs(UnmanagedType.BStr)] string Name,
[In, MarshalAs(UnmanagedType.SafeArray,SafeArraySubType=VarEnum.VT_I4)] ref System.Int32[] InArr,
[Out, MarshalAs(UnmanagedType.VariantBool)] out bool value);
}
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace COMWrapper
{
/// <summary>
/// Zusammenfassung für WrapperGollum.
/// </summary>
[Guid("F96B8D7A-71DE-4ec8-B33D-58CB93A0F654"), ComVisible(true), ClassInterface(ClassInterfaceType.None)]
public class YellowWrapper : IYellowWrapper_1
{
/// <summary>
/// Standardkonstruktor
/// </summary>
public YellowWrapper()
{
}

    /// &lt;summary&gt;  
    /// Gibt ein String Array zurück  
    /// &lt;/summary&gt;  
    /// &lt;returns&gt;&lt;/returns&gt;  
    public void GetArray(System.Int16 data, string Name, ref System.Int32[] IntArr, out bool Result)  
    {  

        //...  
    }  
}  

}

L
Larsen Themenstarter:in
192 Beiträge seit 2006
vor 16 Jahren

Danke,
das werd ich mal ausprobieren!

Gruß
Larsen

...............Es gibt 10 Arten von Menschen ...............
die einen kennen binäre Zahlen, die anderen nicht!!!