OLE automaatio, Visual C++ (MFC) server ja VBA client

Seuraa 
Viestejä45973
Liittynyt3.9.2015

Toivottavasti täältä löytyy joku, joka on ollut asian kanssa tekemisissä. Infoa on ollut aivan tuskastuttavan vaikeaa löytää mistään. Käytössäni on aiheesta perusteos, jossa käydään alkeet läpi, mutta tosiaankin vain alkeet.

Yritän saada aikaan serverin, joka pystyisi ottamaan metodeissaan vastaan olioparametreja. Nämä oliot olisivat saman serverin implementoimia mutta VBA- koodin luomia instansseja.

Ongelma on siinä, että parametrit voidaan määritellä vain variant- rakenteen avulla. Olion voi näköjään välittää variantin LPDISPATCH:in avulla, mutta se ei ole kovin hyvä vaihtoehto VBA clientin käyttäjän kannalta. VBA koodissa olisi tietenkin parasta, jos parametria välitettäväksi koodattaessa koodiin kelpaisi vain ja ainoastaan halutun luokan olio.

Niin, onkohan kukaan teistä ratkaissut kyseistä ongelmaa vai tietääkö joku onko se yleensä ratkaistavissa?

Kommentit (8)

Vierailija

Sinulla on varmaan syysi miksi haluat tehdä asian tuolla viisiin, etkä esimerkiksi DCOMin tai jonkun itse tehdyn rajapinnan avulla, jos haluat kerta käyttää jo vähän vanhentunutta DNA arkkitehtuuria esim. .NET:n sijaan.

Minä tekisin oman recordset tyyppisen luokan jota käyttäisin viestien välityksessä ja sen päälle kerroksen joka muuntaa ko. sanomarakenteen halutuksi olioksi ja kutsuu sitten haluttua metodia.

Vierailija

Kirjoittelin vastausta jo muutama päivä sitten, mutta sen valmistuminen muun työn lomassa kesti sen verran kauan, että istunto vanheni ja viesti lähti "lähetä" painamisen yhteydessä suoraan bittitaivaaseen (kulkematta lähtöruudun kautta).

Nyt sain hermonriekaleet kuriin ja päätin kirjoittaa uudestaan - vähän lyhyemmän version tosin.

Nuutti
Sinulla on varmaan syysi miksi haluat tehdä asian tuolla viisiin, etkä esimerkiksi DCOMin tai jonkun itse tehdyn rajapinnan avulla, jos haluat kerta käyttää jo vähän vanhentunutta DNA arkkitehtuuria esim. .NET:n sijaan.

Joo. Mulla ei oo käytössä kovin uusia materiaaleja. "Tehokäyttäjän opas Visual C++" vuodelta 1997 ja hieman uudempi kirja VC++ 6.0 versiosta, jossa COM teknologiaa ei kovin tarkasti läpikäydä. Ja pisteenä asialle on se, että käytössäni on Office 2000, jossa ei käsittääkseni ole .NET tukea.

Nuutti
Minä tekisin oman recordset tyyppisen luokan jota käyttäisin viestien välityksessä ja sen päälle kerroksen joka muuntaa ko. sanomarakenteen halutuksi olioksi ja kutsuu sitten haluttua metodia.

Saisitko oman toteutuksesi sellaiseksi, että ko ratkaisu ei näkyisi VBA- koodaajalle? Eli hän kuvittelisi antavansa koodissaan tietyn C++ serverissä toteutetun luokan olion parametrina esim jonkin toisen serverissä olevan luokan olion funktion kutsussa. Vba- koodaajan kirjoittamassa olio.teeJotain(....... parametrilistassa näkyisi luokan nimi.

Vierailija
kingofthelake

Saisitko oman toteutuksesi sellaiseksi, että ko ratkaisu ei näkyisi VBA- koodaajalle? Eli hän kuvittelisi antavansa koodissaan tietyn C++ serverissä toteutetun luokan olion parametrina esim jonkin toisen serverissä olevan luokan olion funktion kutsussa. Vba- koodaajan kirjoittamassa olio.teeJotain(....... parametrilistassa näkyisi luokan nimi.

Nyt sorrun varmaankin todella tyhmään kysymykseen, mutta kuitenkin: Mikäs tuossa on ongelmana?

Jep... En käytä VisualC:tä enkä tuohon vba:han ole koskaan tutustunut, kun ei ole ollut tarvetta, mutta onko tuossa nyt jokin vba:n funktio kutsuihin liittyvä knobbi jota en tajua vai mikä?

Vierailija
Calerae
kingofthelake

Saisitko oman toteutuksesi sellaiseksi, että ko ratkaisu ei näkyisi VBA- koodaajalle? Eli hän kuvittelisi antavansa koodissaan tietyn C++ serverissä toteutetun luokan olion parametrina esim jonkin toisen serverissä olevan luokan olion funktion kutsussa. Vba- koodaajan kirjoittamassa olio.teeJotain(....... parametrilistassa näkyisi luokan nimi.



Nyt sorrun varmaankin todella tyhmään kysymykseen, mutta kuitenkin: Mikäs tuossa on ongelmana?

Jep... En käytä VisualC:tä enkä tuohon vba:han ole koskaan tutustunut, kun ei ole ollut tarvetta, mutta onko tuossa nyt jokin vba:n funktio kutsuihin liittyvä knobbi jota en tajua vai mikä?


Visual C++:lla (muutamista muistakin kielistä myös) voidaan tehdä exe- tai dll tiedosto, jonka mm yksilöllinen tunniste ja sijaintipolku rekisteröidään Windowsin rekisteriin. Samoin rekisteriin talletetaan tiedot luokista, jotka sisältyvät kyseiseen dll:ään tai exe:een. Kyse on COM- tekniikasta, joka mahdollistaa ohjelmointirajapinnan toteutuksen Windows ohjelmien välille.

OLE automation on yksi OLE:n/COM:in osa. Se mahdollistaa esim sen, että mm C++:lla voi kirjoittaa koodimodulin, jota VBA:ssa voi hyväksikäyttää kuin mitä tahansa muuta vba-koodia.

Samoin VC++ ohjelma voi toisessa tapauksessa ohjata esim Exceliä ja sallii muodostaa Excelin objekteja c++ koodissa.

Asiaan liittyy tbl-tiedosto, joka sisältää tuon c++ moduulin objektien ja funktioiden nimet. Tällöin VBA koodaaja voi luoda tuon modulin sisältämän olion koodissaan ja kirjoittaa metodikutsuja. Metodivaihtoehdot tulevat näkyviin [olio.] jälkeen ja parametridropdownlista avautuu ohjelmoijan valittua metodin ja sulkumerkin. Taasen näkyvät mahdolliset parametrit listassa.

Palikkaa voi siis vba- koodissa käyttää täysin tietämättä siihen liittyvistä moduleista, rekisterimerkinnöistä ja modulin toteutuskielestä. Riittää kun lisää yhden pienen rastin ruutuun eräässä asetuksessa.

Ja mikä hyöty tuosta kaikesta on?

Toteutin kerran ison vba- projektin ja sen kanssa meinasi mennä hermot oikein kunnolla. Olio- kielellä ja kunnollisella luokkakirjastolla projekti olisi ollut paljon helpompi toteuttaa. Vba:ta olisi voinut käyttää esim vain kutsumaan tuota C++ modulia, jos olisin tuolloin osannut käyttää OLE automaatiota.

Vierailija
kingofthelake

Palikkaa voi siis vba- koodissa käyttää täysin tietämättä siihen liittyvistä moduleista, rekisterimerkinnöistä ja modulin toteutuskielestä. Riittää kun lisää yhden pienen rastin ruutuun eräässä asetuksessa.

No sitähän minäkin. Eli homma toimii siis aivan kuten ajattelinkin.

On tuo ole/com/dcom, etc minulle entuudestaan tuttua tavaraa, mutta kun en tuota VBA:ta tunne, niin jäinpähän vaan hämmästelemään.

Vierailija
Ongelma on siinä, että parametrit voidaan määritellä vain variant- rakenteen avulla. Olion voi näköjään välittää variantin LPDISPATCH:in avulla, mutta se ei ole kovin hyvä vaihtoehto VBA clientin käyttäjän kannalta. VBA koodissa olisi tietenkin parasta, jos parametria välitettäväksi koodattaessa koodiin kelpaisi vain ja ainoastaan halutun luokan olio.

LPDISPATCH on sama kuin IDispatch*. Siksi se pystyy ottamaan vastaan kokonaisen Automaatio-olion. Odl tiedostoa muokkaamalla sain aikaan sen, että VBA- koodaaja näkee olion parametria kirjoittaessaan "as CBank" (automaatiopalvelimessa käyttämäni luokan tunnus) eikä enää "as Object". Tämä taitaa olla riittävä ratkaisu, koska hyvällä dokumentaatiolla sekaannuksia ei tässä kohdin pitäisi sattua.

Vielä kun saisi ratkaisun sille, että vba- editori herjaisi "type mismatch" ilmoituksella, jos parametriksi yrittää kirjoittaa väärän luokan olion tunnuksen.

EDIT: no, tuli tuota väärän tyypin hallitsemista aidoilla vba objekteilla ja näytti tuo type mismatch tapahtuvan ajonaikaisesti.

Vierailija

Eipä ole tullut OLE:n tai COM:n kanssa hetkeen säädettyä.

Taannoin kuitenkin lukaisin kertauksen vuoksi hieman perusteita läpi (ja oikeastaan perusteita aiheesta vasta hallitsenkin).

dll ja (tai oikeastaan) exe palvelimien osalta tulin pohtineeksi, onko palvelimen tarkoitus palvella ainostaan palvelua pyytänyttä asiakasta? ts oliot luodaan luokkatehtaan toimesta vain sen käyttöön. Ja mahdollisten muiden asiakkaiden luomat oliot eivät siis ole sen käytössä.

Vai onko olemassa myös tilanteita, jossa exe palvelin on jo ajossa ja oliot luotuna ja uusi asiakas voi sitten pyytää rajapintojen kautta palveluja niiltä? Lähinnä minua kiinnostaisi saada palveluja tätä kautta suoraan käyttöjärjestelmältä...

Uusimmat

Suosituimmat