Nya utgåvor av "1C: Trade Management": uppdatering utan utveckling. Den operativa redovisningen blir reglerad


Detta beror på några särdrag hos den globala kontextfunktionen ConnectExternalComponent() .

Ofta har programmerare problem med att ansluta externa komponenter (till exempel drivrutiner för kommersiell utrustning) när användare arbetar med 1C, ansluter till servern via en terminal.

I det här fallet ser användarna till exempel den här bilden:

När du arbetar från lokala datorer finns det inga problem med att ansluta externa komponenter.

Vad är detta kopplat till? Detta beror på att när användare arbetar via en terminalserver har de färre rättigheter än när de arbetar på en lokal dator.

Du kan enkelt verifiera detta om du loggar in på terminalservern under ett konto med administrativa rättigheter.

Anledningen till denna skillnad är att 1C inte kan registrera en extern komponent i registret när användaren arbetar i terminalen under normala rättigheter, eftersom en vanlig användare har inte behörighet att skriva till systemregistergrenen HKEY_CLASSES_ROOT.

Publikationer om ämnet att ansluta externa komponenter i terminalen erbjuder en mängd olika metoder för att lösa detta problem.

Till exempel dessa:

1. Starta 1C för första gången under administrativa rättigheter.

Det här alternativet fungerar inte alltid. Jag ska förklara varför nedan.

2. Ge vanliga terminalanvändare behörighet att skriva till systemregistergrenen HKEY_CLASSES_ROOT.

Det är bättre för otillräckligt "avancerade" användare att inte göra detta, annars kan det uppstå problem.

3. Använd olika prylar, registrera VK på uppdrag av en användare med fullständiga rättigheter.

Det är inte heller bra att äta.

Så vad är det bästa sättet att ta sig ur den här situationen?

Jag erbjuder min lösning på detta problem. Enligt min mening - enkel och vacker.

När jag undersökte det här problemet ställde jag mig frågan: varför försöker 1C ens registrera VK med en ny sökväg? Hon är trots allt redan registrerad i systemet.

Poängen visade sig vara att i typiska 1C-konfigurationer (till exempel "Trade Management") används följande syntax för den globala kontextmetoden Connect External Component():

ConnectExternalComponent("Directory.ConnectedEquipment.Layout.DriverATOLBarcodeScanner", "ATOLScanner");

Som du kan se är drivrutinen VC ansluten från layouten "ATOLBarcode Scanner Driver" i katalogen "Connected Equipment".

Vad händer då?

1C sparar komponenten i användarens temporära mapp, till exempel "C:\Documents and Settings\User\Local Settings\Temp\1032\v8_4_12.tmp"

och försöker registrera den i registergrenen HKEY_CLASSES_ROOT precis längs denna väg.

På terminalen har vanliga användare inte rättigheter att ändra denna registergren, så komponenten ansluter inte till dem.

Låt oss nu prata om hur man tar sig ur den här situationen.

Den globala kontextmetoden ConnectExternalComponent() har flera syntaxalternativ. Detta är vad vi kommer att använda.

Så, steg för steg:

1. Registrera den externa komponenten med hjälp av verktyget regsvr32.exe på terminalservern i mappen C:\WINDOWS\SYSTEM32 för ett 32-bitars operativsystem eller i mappen C:\WINDOWS\SYSWOW64 för ett 64-bitars operativsystem.

2. Använd ett av två ytterligare syntaxalternativ för metoden ConnectExternalComponent():

Alternativ 1:

ConnectExternalComponent("C:\WINDOWS\SysWOW64\Scaner1C.dll", "ATOLScanner", ExternalComponentType.COM);

DriverObject = New("AddIn.ATOLScanner.Scaner45");

Alternativ 2:

ProgID = "AddIn.Scaner45";

ConnectExternalComponent(ProgID);

DriverObject = New(ProgID);

Enligt min mening är alternativ nummer 2 att föredra.

Samtidigt försöker 1C inte omregistrera VK:n med en ny sökväg i registret och därmed är alla problem lösta.

Tja, det är allt. Lycka till på jobbet!

[du måste registrera dig för att se länken]

Fråga: Extern komponent Native Api i C++ för Linux (Ubuntu x64) på ​​1C 8.3


Jag skriver till VK, men jag kan inte ansluta till 1c på ubuntu. Inte ens 1s exe ansluter. Så en fråga om det:

1) Jag försöker ansluta VK från VNCOMPS-exemplet som ges i artikeln

(länk finns i slutet: "Kopiering").
Det finns en makefil i NativeApi-projektet. Med dess hjälp bygger jag ett .so-bibliotek på Ununtu.
Men när "Connect External Component" 1c kraschar.
Likaså om jag bygger med "build.sh" (i roten av projektet).

I själva makefilen ändrar jag flaggan från m32 till m64, eftersom 1c och själva x64-systemet. (med parameter m32 ansluter den inte ändå)
Här är ett exempel på att anropa VK från 1C 8.3:
Anslutning klar = ConnectExternalComponent("/home/alexeyubuntux64-20 gb/Documents/VNCOMP83/example/NativeAPI/AddInNative.so", "AddInNative", ExternalComponentType.Native); Det finns en artikel just om detta ämne.
Men så vitt jag ser har alla dessa punkter redan tagits i beaktande och korrigerats i VNCOMPS-exemplet.

Men i grund och botten är det en fråga om kompileringsparametrar. En MB 32-bitars extern komponent ansluts till en 32-bitars 1c normalt, men jag distribuerade den på Ubuntu x64 1c enterprise83 8.3.5-1486 amd64. Och jag vill haka på henne på VK.

Är det någon som har några idéer om hur man löser detta problem?)
VNCOMPS-exemplet borde fungera, men byggparametrarna måste justeras, eller så är själva plattformen som jag testar felaktig.

Svar: Jag undrar, är det möjligt att skriva en extern komponent i Java?

Fråga: Extern komponent (native) kan inte anslutas


Jag sammanställde ett exempel med ITS, för 64 och 32 bitars system.

Jag ansluter så här:
Anslutningsresultat = ConnectExternalComponent(KDLLPath, "Comp", ExternalComponentType.Native); Anslutningen fungerar på en PC, men inte på den andra. Det är skillnad på OS. Där anslutningen görs finns Win7, där det inte finns något Win10. Samtidigt, på datorn där min komponent inte fungerar, fungerar standardkomponenter.

Testad på olika plattformar (8.3.4.482, 8.3.6.2100, 8.3.11.2700, 8.3.12.1412).

Hur kan jag förstå varför det inte går att ansluta?

Svar: vc_redist glömt?

Fråga: 1C8 och en extern komponent med typen Native


God eftermiddag.
Jag har en BP 3.0.50.12-konfiguration och en önskan att implementera vägning från Vesy-Soft-företaget som använder UniServerAuto i den.
Utvecklarna kompilerade komponenten i Native för Windows 32 och 64 och arkiverade den med maifest-filen. Det finns också ett exempel för 1C på hur vikt kan beräknas. I den, med hjälp av en layout med binära data, indikeras detta arkiv, som jag förstår det. I exemplet är allt bra: komponenten är installerad, ansluten, sedan upprättas anslutningen och vikten avläses.
Men så fort du börjar överföra den till 1C läses inte vikten av. Allt verkar vara enkelt skrivet, men jag förstår inte var raken är.
Den som har lite tid - hjälp, ta en titt med ett öga, kanske är lösningen på ytan, men jag går någonstans på fel ställe och gör fel sak. Jag har aldrig behövt arbeta med Native Technology förut...

Och i bilagan finns min bearbetningstext

Svar:

Tja, jag har nyheter...
Jag började bara steg för steg se vid vilken tidpunkt det skulle börja misslyckas. För att göra detta skapade jag en tom databas och bearbetade den med kommandot. I analogi med leverantörens exempel överförde jag layouten till en ny konfiguration - den fungerar andra gången. De där. första gången nej, men andra gången ja. Detta föranledde tanken att det i vår bearbetning fortfarande skulle vara nödvändigt att separera anslutningen av komponenten och objektet enligt olika procedurer.
Sedan överförde jag det till min databas med anslutningen av layouten - det fungerar. Puh, det är bra.... Men jag skulle vilja utan att göra ändringar i konfigurationen, så låt oss gå vidare

Jag försöker lägga till layouten i bearbetningen. Dess storlek ökar omedelbart från 10kb till 3mb och en betydande nedgång i driften märks - det är inte lämpligt. Jag börjar gräva i att ansluta komponenter via dll. De där. i stort sett samma som där jag började. Men det finns ett "MEN": när jag sökte efter dll-namnet i användarens mapp, märkte jag att denna dll finns där (som jag förstår det) de dlls som är registrerade i 1C läggs ihop:
C:\Users\USER\AppData\Roaming\1C\1cv8\ExtCompT
Följaktligen finns det inget behov av att använda hela sökvägen till dll, du kan helt enkelt ange dess namn:
ConnectExternalComponent("Add1CUniServerAuto32.dll", "UniServerAuto", ExternalComponentType.Native);

Jag försöker... den svär vid registrering, men ger vägningsresultatet. Det visar sig att dll-filen redan är registrerad och det betyder att du bara behöver ansluta den. Jag tar bort den och allt fungerar.
För att summera:
1. Vid vägningsbearbetning innefattade AtOpening-proceduren anslutning av en extern komponent och en anslutning till ett objekt.
2. Sökväg till dll-filen Jag skrev inte den, jag angav bara dess namn.

Nu sitter jag och funderar, när installerades dll i 1C? Vid tidpunkten för mjukvaruinstallation? Knappast... När utvecklarkonfigurationen av denna dll körs, var installeras den när formuläret öppnas? Jag vet inte, men det verkar nära mig... Vad tycker du?
Och för det andra, på en ny plats, när det finns ett behov av att installera samma terminal, vad behöver göras för att allt ska fungera? Ska jag installera programvaran fullständigt, köra leverantörens konfiguration för att kontrollera operationen och sedan (i teorin) ska min bearbetning fungera? Något är på något sätt komplicerat... Eller ska jag installera extern komponent en gång i min bearbetning efter att jag har installerat programvaran?

Jag skulle gärna höra dina tankar om detta...

Fråga: Extern component.dll


Goddag allihop.
En fråga.
En dll-komponent som fungerar utmärkt i 1C 7.7
1s 8.1 vill inte starta alls...
Jag försökte klistra in den i C:\Program Files\1cv81\bin\cache1c.dll
Jag försökte registrera mig med regsvr32 "C:\Program Files\1cv81\bin\cache1c.dll"
Registrerar utan problem.
När jag vill komma åt den får jag ett felmeddelande:

Fel vid laddning av extern komponent! cache1c.dll
Procedure ButtonExecutePress(Button) Försök att ladda extern komponent( "C:\Program Files\1cv81\bin\cache1c.dll"); Undantagsrapport( "Fel vid laddning av extern komponent!"+ "cache1c.dll" ); Slutförsök; Försök // Hämta komponentobjektet. // m = Ny ("cache1c.GTMcmd" ); m = New COMObject("cache1c.GTMcmd" ); Undantagsrapport(); Slutförsök; Slutprocedur

Svar: Det är banalt till den grad omöjligt...
Du måste pausa mellan samtalen (millisekunder)...
Procedur ButtonExecutePress(Button) Försök // Hämta ett komponentobjekt. m = New COMObject("cache1c.GTMcmd" ); Undantagsrapport( "Det gick inte att skapa ett externt komponentobjekt"); Slutförsök; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Connect(); m.Paus(100); ...... etc
För 1c 7.7 - detta är inte nödvändigt, det visar sig att hanteringen är snabbare.

Fråga: Arbeta med en extern komponent med en 1C-server...


God eftermiddag,

Det finns en extern komponent skriven i C++, vars uppgift är att hämta information från en extern databas och returnera frågeresultatet i form av en värdetabell i 1C.
För att generera en värdetabell för det aktuella ögonblicket används IDispatch* pBackConnection-gränssnittet, mottaget som en parameter i Init()-funktionen. Därefter använder jag helt enkelt 1C-funktioner för att skapa en värdetabell, fylla den och returnera den till den andra parametern i CallAsFunc(...).
Problem började med övergången till 1C tunna klienter. På serversidan startar inte den externa komponenten riktigt. Du kan köra det på klientsidan, men det hela ser ut som kryckor och faller ur den allmänna "klient-server"-logiken i 1C. Till exempel förstår inte klienten vad en värdetabell är, problem med "globala" variabler, sessioner osv.
NativeAPI är ännu mer begränsad i detta avseende.
Att dansa med en tamburin ledde till att jag kunde starta en extern komponent under 1C-servern, MEN arbetet fortsätter tills ett försök görs att anropa Invoke på pBackConnection. 64-bitarsversionen av 8.2-servern försöker göra något tills den tar timeout, 32-bitarsversionen (VK är naturligtvis också 32-bitars) bara faller av direkt.
Jag antar att 1C-servern inte stöder detta driftläge.
Följaktligen uppstår frågor: är detta tillfälligt eller går 1C-logiken ner på att avbryta detta arbetsschema? Om det är omöjligt att skapa interna 1C-strukturer (värdetabell) på detta sätt, finns det i princip en beskrivning av vad en värdetabell är på systemnivå för att försöka skapa den i C++, fyll i det, och sedan helt enkelt glida 1C som en returparameter? Jag skulle vilja åtminstone få en riktning åt vilket håll jag ska gräva.

Tack.

Svar:

Du skriver en sak och menar en annan.
I 1C-miljön är det inte omöjligt att deklarera variabler som kommer att vara synliga i olika sessioner nu, och det fanns ingen sådan möjlighet tidigare. En annan session är en fysiskt annorlunda process.
En session är en session som ansluter till en databas, dvs. användarsession. Eller lägger du något eget i detta koncept?

Inom en session var det möjligt, och det är nu möjligt, att deklarera variabler i sessionsmodulen som kommer att leva och vara synliga i sessionen från olika platser... faktiskt, det finns 4 av dem.
- Sessionsmodul;
- Regelbunden applikationsmodul;
- Hanterad applikationsmodul;
- Extern anslutningsmodul.

Jo, naturligtvis måste du komma ihåg sammanhanget. Serverkontexten är inte direkt tillgänglig på klientsidan och vice versa.

Faktum är att 1C-arkitekturen stipulerar att datautbytet kommer att gå till enligt följande:
- med hjälp av parametrar/returer av procedurer/funktioner;
- med hjälp av de så kallade sessionsparametrarna (kan inte vara objekt, men faktiskt synliga i paletten).

En tabell på formuläret... är den kopplad till någon objekttabell (t.ex. bearbetning)? eller inte. Om ja, så är den tillgänglig på servern (&OnServer) och redigera där....

Och ändå, ja, värdetabellen är inte tillgänglig i UV på klientsidan. Tja, det var vad 1C bestämde.

Kom igen! Det fungerar med Excel, det fungerar med FSO och en massa andra saker, men det fungerar inte här. Fånga felet och analysera....

Försök
...
dina handlingar
...
Undantag
str = ErrorDescription();
Slutförsök;

Med moderna hårdvarufunktioner är detta inte ett argument alls.

Bara din personliga åsikt. Har inget med verkligheten att göra. Inte på något sätt. Jag upprepar ännu en gång, 1C fungerar utmärkt med COM. Både med in-proc och out-proc.

Ange koden du använder för att ladda ner och kontakta VK.

Förresten, VK... i ditt fall, är det COM eller Native API?
Om COM, så registrerar du det som... via regsvr32... hur "löser" du då problemet med bitdjup?

Fråga: Installera en extern komponent


Berätta för mig hur man installerar en extern komponent. När följande kod körs visas ett fel. Hitta NameDecl.dll i layouten

Försöker att SetExternalComponent("GeneralLayout.Layout"); Undantag EndTry ;
Fel: Installation av extern komponent misslyckades!

Svar: ()
ConnectExternalComponent("GeneralLayout.Layout", "NameDecl", ExternalComponentType.Native) returnerar FALSE.
New("AddIn.NameDecl.CNameDecl", Undefined) = (()): Skriv odefinierad (AddIn.NameDecl.NameDecl)

Fråga: Den ursprungliga dll-filen ansluter inte till 1c 8.1 (fptrwin32_fz54_9_11_0_5549.dll)


Hallå.
1C uppdaterade dll-filen för onlinekassor atol för ffd 1.05 (ingår i underhållsbearbetningen fptrwin32_fz54_9_11_0_5549.dll).
Jag har en gammal 1C 8.1. Till skillnad från 8.2 stöder den inte att arbeta med extern utrustning på samma sätt som 8.2, så du måste först registrera dll i Windows, och sedan bara ansluta den till 1C?

ProgID = "AddIn.IntegrationComponent.ATOL_KKT_1C83_V9"; LoadExternalComponent("C:\fptrwin32_fz54_9_11_0_5549.dll"); ConnectExternalComponent(progID); Drivrutin = New(ProgID);

Men den gamla bearbetningen skrevs i com "teknik", och den nya är infödd. Följaktligen ger det ett fel när du registrerar regsvr32:
Modulen är laddad, men ingångspunkten för DllRegisterServer hittades inte. Och det föreslår att du kontrollerar att den här filen är rätt dll- eller OCX-fil.
Har någon råkat ut för en liknande situation och hur kom du ut? Jag förstår att 7.7 kommer att ha ett liknande problem.
Kod 8.2:

Layout = GetLayout("IntegrationComponent"); Adress = PlaceInTemporaryStorage(Layout); ConnectExternalComponent(Adress, "IntegrationComponent", ExternalComponentType.Native); Driver = New("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9");

1C 8.2:
ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
1C 8.1:
ConnectExternalComponent(<Идентификатор объекта>)
Alternativ:
<Идентификатор объекта>(nödvändig)
Typ: Sträng. ProgID (Programmatic Identifier) ​​för det externa komponentobjektet. Ska motsvara uppgifterna i systemets registreringsdatabas (Registry).
Beskrivning:
Ansluter externa komponentobjekt till 1C:Enterprise.
Ej tillgängligt på 1C:Enterprise-servern. Används inte i den externa anslutningsmodulen.
Notera:
Externa komponenter är kompatibla med 1C:Enterprise 7.7-komponenter.
Exempel:
Försök
ConnectExternalComponent("AddinObject.Scanner");
Report("Komponenten för streckkodsläsaren har laddats");
Undantag
Report("Komponenten för streckkodsläsaren är inte laddad");
Slutförsök

Finns det något sätt att ansluta denna dll till 8.1 eller inte?

Tack!

Svar:

Jag har också nyligen stött på detta problem. Det gick inte att konvertera till en senare version av 1c eftersom... dll som den här konfigurationen fungerar med slutade helt enkelt att fungera och 1c kraschade med ett fel.
Jag löste problemet enligt följande:
Jag skapade en tom 8.3-databas där jag bearbetade initieringen av komponenten och sedan från 8.1 via en COM-anslutning fick jag tillgång till den tidigare skapade databasen och initierade komponenten där. Sedan, redan i 8.1, kallade jag metoderna för denna komponent.
Naturligtvis är detta en krycka, men jag har inte hittat någon annan utväg än(

Kodexempel 8.3:
Variabel drivrutinsexport;
Funktion ConnectionComponentsKKT() Export
Försök

Layout = GetLayout("IntegrationComponent");
Adress = PlaceInTemporaryStorage(Layout);
ConnectExternalComponent(Adress, "IntegrationComponent", ExternalComponentType.Native);
Driver = New("AddIn.IntegrationComponent.SMDrvFR1C20");
Resultat = Sant;

Undantag

Resultat = Falskt;

Slutförsök;
Returnera resultat
EndFunction

Kodexempel 8.1

Funktion CreateDriverObject(Driver) Export

Resultat = Sant;

Försök

ConnectionString="File="""Sökväg till databas""";
ComObject = New COMObject("V83.ComConnector");
Connect = ComObject.Connect(ConnectionString);

Processing = Connect.Processing.ConnectExternalComponent.Create();
Anslutningsresultat = Processing.ConnectionCCCPoponents();
Om anslutningen blir resultatet
Drivrutin = Processing.Driver;
EndIf;

Undantag
Alla som har gjort detta eller stött på liknande avgöranden, förklara själva principen med ett enkelt exempel. Det verkar som att allt är klart med att ansluta externa komponenter.

// Exempel på att fylla i värdetabellen TK.Clear(); Request = Ny begäran; Query.Text = "VÄLJ | Nomenclature.Link HUR Nomenklatur |FRÅN | Directory.Nomenclature AS Nomenclature"; Query Result = Query.Execute(); Selection = Query Result.Select(); While Selection.Next() Cycle Page = TK.Add(); FillPropertyValues(Page, Selection); EndCycle;
Kan du använda det här exemplet för att förklara vilken del av koden som vanligtvis tas ut? Det skulle vara logiskt att ta bort delen med begäran, men hur kan vi komma åt databasen från den externa komponenten, förbi plattformen? Det är ingen idé att ta fram texten. Eller ta ut själva bildandet av den tabellformade delen. Dela din erfarenhet med alla som har stött på detta.

Svar: Och att ordet "Inkompatibelt" alltid betyder ordet "dåligt"? Ja, det verkar för mig att om jag kallade min stil "1C: Den sämsta programmeringen på denna skriptmotor som finns i naturen (översatt till litterärt språk)!" och då kommer det nog finnas folk som vill kolla in den här besten. Och det ser ut som en klassiker: "Jag har inte läst Pasternak, men jag håller helt inte med honom!"

Fråga: Ansluta en extern komponent i 1s 8.3.6 och Win8


Du måste ansluta den externa komponenten vk_rs232.dll till den anpassade konfigurationen. Det verkar ha registrerats via regsvr32.exe. "Det verkar" eftersom jag fick ett meddelande att "komponenten är registrerad, men det är något fel med brandväggen." Jag litar på den första halvan av meddelandet och skriver koden i 1C
AfterConnecting = New Alert Description("AfterConnectingVK", ThisForm); StartInstallingExternalComponents(,"C:\Controller\vk_rs232.dll"); StartConnectingExternalComponents(AfterConnecting,"C:\Controller\vk_rs232.dll","DLL_Scales");
och jag får felet att
"Installationen av en extern komponent misslyckades! En komponent för klientprogrammet du använder kan saknas!".

Och nu förstår jag inte:
1. Komponenten kanske inte är registrerad i registret - hur kan jag kontrollera den där?
2. Kanske fungerar inte dess "version" under Win8, även om jag har den 32-bitars.
3. Kanske är 1C i sig för ny, d.v.s. Följaktligen kan det inte fungera med denna dll?
4. Tja, det är trivialt - jag skriver något fel.

Svar: Och allt detta ledde mig till nästa problem. VneshComp är installerat, nu måste du ansluta det. Och här är båda alternativen
ConnectExternalComponent("C:\Controller\vk_rs232.dll","Vågen")
ConnectExternalComponent("GeneralLayout.Layout","Vågen")

Syntaxalternativ: Efter namn och plats

Syntax:

ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
Alternativ:

<Местоположение>(nödvändig)

Typ: Sträng.
Placeringen av den externa komponenten.
Platsen kan användas:
sökväg till den externa komponentfilen på filsystemet (inte tillgänglig på webbklienten), inte ett ZIP-arkiv;
det fullständiga namnet på layouten som lagrar binärdata eller ZIP-arkiv;
URL:en till den externa komponenten, som binär data eller ett ZIP-arkiv, i ett format som liknar GetNavigationLink.
<Имя>(nödvändig)

Typ: Sträng.
Det symboliska namnet på den externa komponent som ska anslutas.
Namnet måste följa det inbyggda språkets namnkonventioner.
<Тип>(frivillig)

Typ: ExternalComponentType.
Typ av extern komponent som ska anslutas.
Används inte om komponenten är förpackad i ett ZIP-arkiv.
Beskrivning av metodalternativet:

Ansluter komponenter tillverkade med Native och COM-teknik.
Komponenten kan lagras i infobasen eller konfigurationslayouten som binär data eller i ett ZIP-arkiv.
För startlägena "Tunn klient" och "Webbklient" måste komponenten först installeras med metoden Installera extern komponent.
Syntaxalternativ: Efter ID

Syntax:

ConnectExternalComponent(<ИдентификаторОбъекта>)
Alternativ:

<ИдентификаторОбъекта>(nödvändig)

Typ: Sträng.
Identifierare för det externa komponentobjektet i form av ProgID (Programmatic Identifier) ​​i MS Windows-registret (till exempel: "AddIn.Scanner").
Ska motsvara uppgifterna i systemets registreringsdatabas (Registry).
Beskrivning av metodalternativet:

Komponenten måste implementeras med COM-teknik och registreras i MS Windows-registret.
Dessa komponenter är kompatibla med 1C:Enterprise 7.7-komponenter.
Uppmärksamhet! Metodalternativet fungerar inte på servern och i den externa anslutningen.
Returvärde:

Typ: Boolean.
Sant - anslutningen lyckades.
Beskrivning:

Ansluter en extern komponent till 1C:Enterprise.
Externa komponenter kan lagras i infobas eller konfigurationslayouter som ett ZIP-arkiv eller som binär data, eller i en filsystemfil.
När du arbetar på en tunn klient och en webbklient måste komponenten vara förinstallerad.

Tillgänglighet:

Tunn klient, webbklient, server, extern anslutning.
Notera:

Externa komponenter kan implementeras med hjälp av Native API eller COM-teknik. Komponenter tillverkade med COM-teknik är kompatibla med 1C:Enterprise 7.7-komponenter.
Webbklienten kan endast arbeta med komponenter i infobasen som är paketerade i ett arkiv.
Den tunna klienten kan arbeta med komponenter i infobasen, paketerade i ett arkiv, och komponenter som finns i filsystemet.
Den tjocka klienten kan hantera alla komponentlagringsalternativ. I det här fallet, om en komponent installeras med metoden Installera extern komponent, används den installerade komponenten, och om den inte är installerad kommer komponenten att tas emot vid anslutningstillfället.
Servern kan fungera med alla komponenter. Komponenten cachelagras per serversession.
Exempel:

Om ConnectExternalComponent("AddinObject.Scanner") Då
Report("Komponent för streckkodsläsare laddad");
Annat
Report("Komponenten för streckkodsläsaren är inte laddad");
endIf;

  • Handledning

Introduktion

Den här artikeln ger en uppfattning om hur externa komponenter fungerar i 1C: Enterprise-systemet.
Processen för att utveckla en extern komponent för 1C: Enterprise system version 8.2, som körs under Windows OS med ett filläge, kommer att visas. Det här alternativet används i de flesta lösningar som är designade för småföretag. VK kommer att implementeras i programmeringsspråket C++.

Externa komponenter "1C: Enterprise"

"1C: Enterprise" är ett utbyggbart system. För att utöka systemets funktionalitet används externa komponenter (EC). Ur utvecklarens synvinkel är en VC ett externt objekt som har egenskaper och metoder, och som även kan generera händelser för bearbetning av 1C: Enterprise-systemet.
Externa komponenter kan användas för att lösa en klass av problem som är svåra eller till och med omöjliga att implementera i programmeringsspråket inbyggt i 1C: Enterprise. I synnerhet inkluderar denna klass uppgifter som kräver interaktion på låg nivå med operativsystemet, till exempel för att arbeta med specifik utrustning.
1C: Enterprise-systemet använder två tekniker för att skapa externa komponenter:
  • använder Native API
  • använder COM-teknik
Med tanke på de givna begränsningarna är skillnaden mellan de två ovan nämnda teknikerna obetydlig, så vi kommer att överväga utvecklingen av videospel med hjälp av Native API. Vid behov kan de implementerade utvecklingarna tillämpas på utvecklingen av datorprogramvara med COM-teknik, och även, med mindre ändringar, appliceras för användning i 1C: Enterprise-systemet med andra driftsalternativ än fildriftsläget.
VK struktur
Den externa komponenten i 1C: Enterprise-systemet presenteras i form av ett DLL-bibliotek. Bibliotekskoden beskriver descendant-klassen IComponentBase. Den skapade klassen måste definiera metoder som är ansvariga för att implementera den externa komponentens funktioner. De åsidosatta metoderna kommer att beskrivas mer i detalj nedan när materialet presenteras.

Lanserar en demo VK

Uppgift:
  1. Montera en extern komponent som levereras med ett ITS-abonnemang och som är avsedd att demonstrera huvudfunktionerna hos den externa komponentmekanismen i 1C
  2. Anslut demokomponenten till 1C-konfigurationen
  3. Se till att de deklarerade funktionerna fungerar korrekt
Kompilering
Demo-VK finns på ITS-prenumerationsskivan i katalogen “/VNCOMP82/example/NativeAPI”.
För att bygga demo-VC kommer vi att använda Microsoft Visual Studio 2008. Andra versioner av denna produkt stöder inte Visual Studio-projektformatet som används.


Öppna AddInNative-projektet. I projektinställningarna inkluderar vi katalogen med huvudfilerna som behövs för att bygga projektet. Som standard finns de på ITS-disken i katalogen /VNCOMP82/inkludera.
Resultatet av bygget är filen /bind/AddInNative.dll. Detta är det kompilerade biblioteket för att ansluta till 1C-konfigurationen.
Ansluter VK till 1C-konfiguration
Låt oss skapa en tom 1C-konfiguration.
Nedan finns koden för den hanterade applikationsmodulen.
variabel DemoComp; Procedur när systemet startar() Connect External Component("...\bind\AddInNative.dll", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); Slutprocedur
Om inget fel rapporterades när 1C-konfigurationen startas, var VK framgångsrikt ansluten.
Som ett resultat av exekvering av ovanstående kod visas ett objekt i konfigurationens globala synlighet DemoComp, som har egenskaper och metoder som definieras i koden för den externa komponenten.
Demonstration av den inbyggda funktionaliteten
Låt oss kontrollera funktionaliteten hos demo VK. För att göra detta, låt oss försöka ställa in och läsa några egenskaper, anropa några VK-metoder och även ta emot och bearbeta VK-meddelandet.
Dokumentationen som finns på ITS-disken anger följande funktionalitet hos demo-VC:n:
  1. Hantera komponentobjekttillstånd
    Metoder: Sätta på, Stäng av
    Egenskaper: Ingår
  2. Timerhantering
    Varje sekund skickar komponenten ett meddelande till 1C: Enterprise-systemet med parametrar Komponent, Timer och en systemklockräknarlinje.
    Metoder: StartTimer, Stoppa timer
    Egenskaper: Det finns en timer
  3. Metod ShowInStatusLine, som visar i statusraden texten som skickats till metoden som parametrar
  4. Metod Ladda upp bild. Laddar en bild från den angivna filen och överför den till 1C: Enterprise-systemet i form av binär data.
Låt oss se till att dessa funktioner fungerar. För att göra detta, kör följande kod:
variabel DemoComp; Procedur när systemet startar() ConnectExternalComponent(...); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Disable(); Rapport(DemoComp.Enabled); DemoComp.Enable(); Rapport(DemoComp.Enabled); DemoComp.StartTimer(); Procedurslut Procedur Extern händelsebearbetning (Källa, Händelse, Data) Rapport (Källa + " " + Händelse + " " + Data); Slutprocedur
Resultatet av att köra konfigurationen visas i bilden


Panelen "Meddelanden" visar resultaten av metodanrop DemoComp.Disable() Och Demo.Comp.Enable(). Efterföljande rader i samma panel innehåller resultaten av bearbetning av meddelanden som tagits emot från VK - Källa, Händelse Och Data respektive.

Anpassat namn på extern komponent

Uppgift: Ändra namnet på den externa komponenten till ett godtyckligt namn.
I föregående avsnitt användes identifieraren AddInNativeExtension, vars innebörd inte förklarades. I detta fall AddInNativeExtension- detta är namnet på tillägget.
VK-koden definierar en metod RegisterExtensionAs, returnerar namnet till 1C: Enterprise-systemet, vilket är nödvändigt för efterföljande registrering av VK i systemet. Det rekommenderas att ange en identifierare som till viss del avslöjar essensen av den externa komponenten.
Här är den fullständiga koden för metoden RegisterExtensionAs med tilläggsnamnet ändrat:
bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) ( wchar_t *wsExtension = L"SomeName"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* dest = 0; if (m_iMemory>AlliMinne om(m_iMinne>Alla_Minne) ((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, iActualSize) returnerar falskt;
I det angivna exemplet ändras VK-namnet till SomeName. När du sedan ansluter VK måste du ange ett nytt namn:
DemoComp = New("AddIn.DemoVK.SomeName");

Utökar listan över VK-egenskaper

Uppgift:
  1. Studera implementeringen av VK-egenskaper
  2. Lägg till en read/write-egenskap av strängtyp
  3. Lägg till en läs/skriv-strängegenskap som lagrar datatypen för den senaste egenskapsuppsättningen. Ingen åtgärd vidtas vid inställning av egenskapsvärdet

För att fastställa egenskaperna för komponenten som skapas måste utvecklaren implementera följande metoder i bibliotekskoden AddInNative.cpp:
GetNProps
Returnerar antalet egenskaper för detta tillägg, 0 om det inte finns några egenskaper
FindProp
Returnerar serienumret för egenskapen vars namn skickas i parametrarna
GetPropName
Returnerar namnet på egenskapen med dess serienummer och den passerade språkidentifieraren
GetPropVal
Returnerar värdet på egenskapen med det angivna ordningstalet
SetPropVal
Ställer in värdet på egenskapen med det angivna ordningsnumret
ÄrPropReadable
Returnerar läsbarhetsflaggan för egenskapen med det angivna sekvensnumret
ÄrPropWritable
Returnerar skrivbarhetsflaggan för egenskapen med det angivna sekvensnumret


Låt oss överväga implementeringen av ovanstående klassmetoder CAddInNative.
I demo-VC definieras 2 egenskaper: Ingår Och Det finns en timer (är aktiverad Och IsTimerPresent).
I bibliotekskodens globala omfång definieras två arrayer:
statisk wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent"); static wchar_t *g_PropNamesRu = (L"Aktiverad", L"Det finns en timer");
som lagrar ryska och engelska fastighetsnamn. I rubrikfilen AddInNative.h uppräkningen definieras:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Alltid sist );
ePropIsEnabled Och ePropIsTimerPresent, som har värdena 0 respektive 1, används för att ersätta serienumren för egenskaper med meningsfulla identifierare. ePropLast, som har värdet 2, används för att få fram antalet egenskaper (med GetNProps-metoden). Dessa namn används endast inom komponentkoden och är inte tillgängliga från utsidan.
Metoderna FindProp och GetPropName utför arraysökningar g_PropNames Och g_PropNamesRu.
För att lagra värdena för fälten i biblioteksmodulen har CAddInNative-klassen egenskaper som lagrar värdet på komponentegenskaperna. Metoder GetPropVal Och SetPropVal returnera och ställ in värdet på dessa egenskaper i enlighet med detta.
Metoder ÄrPropReadable Och ÄrPropWritable och återvänd Sann eller falsk, beroende på det godkända ordningsnumret för egenskapen i enlighet med applikationslogiken.
För att lägga till en anpassad egenskap måste du:

  1. Lägg till namnet på egenskapen som läggs till i arrayer g_PropNames Och g_PropNamesRu(fil AddInNative.cpp)
  2. Att lista Rekvisita(fil AddInNative.h) innan ePropLast lägg till ett namn som unikt identifierar egenskapen som läggs till
  3. Organisera minne för att lagra egenskapsvärden (skapa modulkomponentfält som lagrar motsvarande värden)
  4. Gör ändringar i metoder GetPropVal Och SetPropVal för att interagera med minnet som tilldelats i föregående steg
  5. Gör ändringar i metoderna i enlighet med applikationslogiken ÄrPropReadable Och ÄrPropWritable
Punkterna 1, 2, 5 behöver ingen förklaring. Detaljer om genomförandet av dessa steg kan hittas genom att studera bilagan till artikeln.
Låt oss ge namn till testegenskaperna Testa Och Skriv Check respektive. Sedan, som ett resultat av steg 1, har vi:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"); static wchar_t *g_PropNamesRu = (L"Aktiverad", L"Det finns en timer", L"Test", L"Typkontroll");
Överföra Rekvisita kommer att se ut som:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Alltid sist );
För att avsevärt förenkla koden kommer vi att använda STL C++. I synnerhet för att arbeta med strängar WCHAR, låt oss ansluta biblioteket wstring.
För att spara ett metodvärde Testa, definierar vi i klassen CAddInNative inom ramen för ett privat område:
sträng test1;
För att överföra strängparametrar mellan 1C: Enterprise och externa komponenter, används 1C: Enterprise-minneshanteraren. Låt oss ta en närmare titt på hans arbete. Funktionerna används för att allokera respektive frigöra minne AllocMemory Och Ledigt minne definieras i filen ImemoryManager.h. Om det är nödvändigt att skicka en strängparameter till 1C: Enterprise-systemet måste den externa komponenten allokera minne för den genom att anropa funktionen AllocMemory. Dess prototyp ser ut så här:
virtual bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0;
Var pMinne- adressen till pekaren i vilken adressen till det tilldelade minnesområdet kommer att placeras,
ulCountByte- storleken på det tilldelade minnesområdet.
Ett exempel på minnesallokering för en sträng:
WCHAR_T *t1 = NULL, *test = L"TEST_STRING"; int iActualSize = wcslen(test1)+1; m_iMemory->AllocMemory((void**)&t1, iActualSize * sizeof(WCHAR_T)); ::convToShortWchar(&t1, test1, iActualSize);
För att underlätta arbetet med strängdatatyper kommer vi att beskriva funktionen wstring_to_p. Den tar emot en wstring-sträng som en parameter. Resultatet av funktionen är en fylld struktur tVariant. Funktionskod:
bool CAddInNative::wstring_to_p(std::wstring str, tVariant* val) ( char* t1; TV_VT(val) = VTYPE_PWSTR; m_iMemory->AllocMemory((void**)&t1, (str.length()+1) * sizeof(WCHAR_T)); memcpy(t1, str.c_str(), (str.length()+1) * val -> pstrVal = t1; returnera sant)
Sedan motsvarande fallsektion av switch-satsen för metoden GetPropVal kommer att ha formen:
fall ePropTest1: wstring_to_p(test1, pvarPropVal); ha sönder;
Metod SetPropVal:
fall ePropTest1: if (TV_VT(varPropVal) != VTYPE_PWSTR) returnerar falskt; test1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); ha sönder;
För att implementera den andra egenskapen definierar vi ett klassfält CaddInNative
uint8_t last_type;
där vi kommer att spara typen av det senast överförda värdet. För att göra detta, lägg till kommandot i metoden CaddInNative::SetPropVal:
last_type = TV_VT(varPropVal);
När vi nu begär att få läsa värdet på den andra egenskapen, kommer vi att returnera värdet sista_typ, vad den utsedda uppgiften kräver.
Låt oss kontrollera funktionen hos de ändringar som gjorts.
För att göra detta, låt oss presentera utseendet på 1C-konfigurationen enligt följande:
variabel DemoComp; Procedur när systemet startar() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.TypeCheck = 1; Report(String(DemoComp.TypeCheck)); DemoComp.Test = "Vasya"; Report(String(DemoComp.Test)); DemoComp.Test = "Petya"; Report(String(DemoComp.Test)); Report(String(DemoComp.TypeCheck)); Slutprocedur
Som ett resultat av lanseringen kommer vi att få en sekvens av meddelanden:
3
Vasya
Peter
22

Det andra och tredje meddelandet är resultatet av läsning av egenskapen som sattes in i föregående steg. Det första och andra meddelandet innehåller typkoden för den sista egenskapsuppsättningen. 3 motsvarar ett heltalsvärde, 22 motsvarar ett strängvärde. Överensstämmelsen mellan typer och deras koder fastställs i filen typer.h, som finns på ITS-disken.

Utökar listan över metoder

Uppgift:
  1. Utöka funktionaliteten för den externa komponenten med följande funktionalitet:
  2. Utforska sätt att implementera externa komponentmetoder
  3. Lägg till en funktionsmetod Funktion 1, som tar två strängar ("Parameter1" och "Parameter2") som parameter. Resultatet är en sträng som: "Kontrollerar. Parameter1, Parameter2"
  4. Se till att ändringarna du gör fungerar.

För att definiera metoderna för komponenten som skapas måste utvecklaren implementera följande metoder i AddInNative-bibliotekskoden:
GetNMethods, Hittametod, GetMethodName
Designad för att få motsvarande antal metoder, sök efter numret och namnet på metoden. Liknar motsvarande metoder för fastigheter
Skaffa NParams
Returnerar antalet metodparametrar med det angivna sekvensnumret; om en metod med detta nummer saknas eller inte har några parametrar, returnerar 0
GetParamDefValue
Returnerar standardvärdet för den angivna parametern för den angivna metoden
HasRetVal
Returnerar flaggan att metoden med det angivna ordinarie returvärdet existerar: sant för metoder med ett returvärde och falsk annat
CallAsProc
falsk, uppstår ett körtidsfel och exekveringen av 1C: Enterprise-modulen avslutas. Minne för arrayen av parametrar tilldelas och frigörs av 1C: Enterprise.
CallAsFunc
Utför metoden med det angivna sekvensnumret. Om metoden återkommer falsk, uppstår ett körtidsfel och exekveringen av 1C: Enterprise-modulen avslutas. Minne för arrayen av parametrar tilldelas av 1C: Enterprise. Om returvärdet är en sträng eller binär datatyp allokerar komponenten minne med funktionen AllocMemory minneshanteraren, skriver data där och lagrar denna adress i motsvarande fält i strukturen. 1C: Företaget kommer att frigöra detta minne genom att ringa Ledigt minne.
En fullständig beskrivning av metoderna, inklusive en lista över parametrar, beskrivs i detalj i dokumentationen som finns på ITS-disken.
Låt oss titta på implementeringen av metoderna som beskrivs ovan.
I komponentkoden är två arrayer definierade:
static wchar_t *g_MethodNames = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"); static wchar_t *g_MethodNamesRu = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage");
och uppräkning:
enum Metoder ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Alltid sist );
De används i funktioner GetNMethods, Hittametod Och GetMethodName, i analogi med beskrivningen av fastigheter.
Metoder Skaffa NParams, GetParamDefValue, HasRetVal implementera omkopplare, beroende på de passerade parametrarna och applikationslogiken, returnera det önskade värdet. Metod HasRetVal i sin kod har den en lista över endast metoder som kan returnera ett resultat. För dem återvänder han Sann. För alla stålmetoder returer falsk.
Metoder CallAsProc Och CallAsFunc innehåller direkt körbar kod för metoden.
För att lägga till en metod som bara kan anropas som en funktion måste du göra följande ändringar i källkoden för den externa komponenten:
  1. Lägg till metodnamn till arrayer g_MethodNames Och g_MethodNamesRu(fil AddInNative.cpp)
  2. Lägg till en meningsfull metodidentifierare till metoduppräkningen (fil AddInNative.h)
  3. Gör ändringar i funktionskoden Skaffa NParams enligt programlogik
  4. Om det behövs, gör ändringar i metodkoden GetParamDefValue, om du vill använda standardvärdena för metodparametrarna.
  5. Gör ändringar i funktionen HasRetVal
  6. Gör ändringar i funktionernas logik CallAsProc eller CallAsFunc, placera den direkt körbara koden för metoden där
Låt oss presentera arrayerna g_MethodNames Och g_MethodNamesRu, samt listning Metoder till formuläret:
static wchar_t *g_MethodNames = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"); static wchar_t *g_MethodNamesRu = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test");

Enum-metoder ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Alltid sist );
Låt oss redigera funktionen GetNProps så att det returnerar antalet parametrar för metoden "Test":
long CAddInNative::GetNParams(const long lMethodNum) ( switch(lMethodNum) ( case eMethShowInStatusLine: return 1; case eMethLoadPicture: return 1; case eMethTest: return 2; default: return 0; )
Låt oss göra ändringar i funktionen:
bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) (​TV_VT(pvarParamDefValue)= VTYPE_EMPTY; switch(lMethodNum) (caseable eMethen case:MethEnable:MethEnable MethStartTimer : case eMethStopTimer: case eMethTest : / / Det finns inga parametervärden som standard break default: return false;
Tack vare den tillagda raden
fall eMethTest:
om ett eller flera argument saknas kommer motsvarande parametrar att ha ett tomt värde ( VTYPE_EMPTY). Om du behöver ett standardvärde för en parameter bör du ställa in det i avsnittet eMethTest funktion switch uttalande CAddInNative::GetParamDefValue.
Eftersom testmetoden kan returnera ett värde måste du göra ändringar i funktionskoden HasRetVal:
bool CAddInNative::HasRetVal(const long lMethodNum) ( switch(lMethodNum) (case eMethLoadPicture: case eMethTest: return true; default: return false; ) return false; )
Och lägg till den körbara koden för metoden till funktionen CallAsFunc:
bool CAddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) ( ... std::wstring s1, s2; switch(lMethodNum) (case eMethbreakPicture: ...T case eMethLoadPicture: ...T if (!lSizeArray || !paParams) returnerar false; ;
Låt oss kompilera komponenten och föra konfigurationskoden till formuläret:
variabel DemoComp; Procedur när systemet startar() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); lane = DemoComp.Test("Hej," "Världen!"); Rapport(per); Slutprocedur
Efter att ha startat konfigurationen kommer vi att få meddelandet: "Hello, World!", vilket indikerar att metoden fungerade framgångsrikt.

Timer

Uppgift:
  1. Studera implementeringen av timern i demon VK
  2. Ändra "StartTimer"-metoden genom att lägga till möjligheten att skicka in timerns svarsintervall i parametrarna (i millisekunder)
  3. Se till att ändringarna du gör fungerar.

I WinAPI kan du använda meddelandet för att arbeta med tiden WM_TIMER. Detta meddelande kommer att skickas till ditt program vid det tidsintervall som du ställde in när du skapade timern.
För att skapa en timer, använd funktionen SetTimer:
UINT SetTimer(HWND hWnd, // fönsterdeskriptor UINT nIDevent, // timeridentifierare (nummer) UINT nElapse, // delay TIMERPROC lpTimerFunc); // pekare till funktion
Operativsystemet kommer att skicka ett meddelande WM_TIMER in i programmet med det intervall som anges i argumentet nFörlopp(i millisekunder). I den sista parametern kan du specificera en funktion som kommer att exekveras varje gång timern avfyras. Rubriken för denna funktion bör se ut så här (namnet kan vara vad som helst):
void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Låt oss överväga implementeringen av en timer i demo-VC.
Eftersom vi överväger processen att utveckla en extern komponent för Windows OS-familjen, kommer vi inte att överväga implementeringen av timern i andra operativsystem. För GNU/Linux OS, i synnerhet, kommer implementeringen att skilja sig åt i syntaxen för funktionen SetTimer Och TimerProc.
Den körbara koden anropar metoden SetTimer, till vilken funktionen skickas MyTimerProc:
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
ID:t för den skapade timern placeras i en variabel m_uiTimer så att den kan inaktiveras senare.
Fungera MyTimerProc som följer:
VOID CALLBACK MyTimerProc(HWND hwnd, // handtag för fönster för timermeddelanden UINT uMsg, // WM_TIMER meddelande UINT idEvent, // timeridentifierare DWORD dwTime // aktuell systemtid) (om (!pAsyncEvent) returnerar; wchar_t *who = L "ComponentNative", *what = L"Timer"; wchar_t *wstime = new wchar_t; if (wstime) (wmemset(wstime, 0, TIME_LEN); ::_ultow(dwTime, wstime, 10); pAsyncEvent->ExternalEvent(who , vad, wstime);
Kärnan i funktionen är att metoden kallas ExternEvent, som skickar ett meddelande till 1C: Enterprise-systemet.
För att utöka funktionaliteten i metoden StartTimer Låt oss göra följande:
Ändring av metodkoden Skaffa NParams så att det är för metoden eMethStartTimer returnerade värde 1:
fall eMethStartTimer: return 1;
Här är metodkoden CallAsProc till formuläret:
case eMethStartTimer: if (!lSizeArray || TV_VT(paParams) != VTYPE_I4 || TV_I4(paParams)<= 0) return false; pAsyncEvent = m_iConnect; #ifndef __linux__ m_uiTimer = ::SetTimer(NULL,0,TV_I4(paParams),(TIMERPROC)MyTimerProc); #else // код для GNU/Linux #endif break;
Låt oss nu kontrollera funktionen. För att göra detta kommer vi att skriva koden i den hanterade applikationsmodulen för konfigurationen:
variabel DemoComp; Procedur när systemet startar() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.StartTimer(2000); Slutprocedur
Efter att ha startat konfigurationen kommer programmet att ta emot meddelanden med intervaller på 2 sekunder, vilket indikerar att timern fungerar korrekt.

Interaktion med 1C: Enterprise-systemet

För att interagera mellan den externa komponenten och 1C: Enterprise-systemet, metoder i klassen IAddInDefBase, som beskrivs i filen AddInDefBase.h. Vi listar de mest använda:
Genererar ett felmeddelande
virtuell bool ADDIN_API AddError (osignerad kort wcode, const WCHAR_T* källa, const WCHAR_T* descr, long scode)
wcode, scode- felkoder (en lista med felkoder med beskrivningar finns på ITS-disken)
källa- felkälla
beskrivning- felbeskrivning
Skickar ett meddelande till 1C: Enterprise-systemet
virtuell bool ADDIN_API ExternalEvent(WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;
wszSource- meddelandekälla
wszMessage- Meddelandetext
wszData- överförda data
Meddelandeavlyssning utförs av External Event Processing-proceduren
Registrering av en extern komponent i 1C: Enterprise-systemet
virtuell bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszProfilnamn- komponentnamn.
Dessa metoder är tillräckliga för full interaktion mellan VK och 1C. För att ta emot data av en extern komponent från 1C: Enterprise-systemet och vice versa, skickar den externa komponenten ett speciellt meddelande, som i sin tur fångas upp av 1C-systemet och vid behov anropar den externa komponentens metoder för att överföra data tillbaka .

tVariantdatatyp

Vid utbyte av data mellan den externa komponenten och 1C: Enterprise-systemet används datatypen tVariant. Det beskrivs i filen types.h, som finns på ITS-disken:
struct _tVariant ( _ANONYMOUS_UNION union ( int8_t i8Val; int16_t shortVal; int32_t lVal; int intVal; osignerad int uintVal; int64_t llVal; uint8_t ui8Val; uint2_Valt; uint2_Valt ; uint t32_t errCode; float fltVal; struct tmVal; void* pInterfaceVal __VARIANT_NAME_2/*iface*/; uint32_t strLen ;//count of bytes ) __VARIANT_NAME_1 ; dimensionell array i pvarVal TYPEVAR vt);
Typ tVariantär en struktur som inkluderar:
  • blandning (union) avsedd direkt för datalagring
  • datatypsidentifierare
I allmänhet arbetar med variabler av typ tVariant sker enligt följande algoritm:
  1. Bestämma vilken typ av data som för närvarande lagras i en variabel
  2. Gå till motsvarande blandningsfält för att få direkt tillgång till data
Använder typen tVariant avsevärt förenklar interaktionen mellan 1C: Enterprise-systemet och externa komponenter

Ansökan

Katalogen "exempel" innehåller exempel för artikeln
exempel/1 - starta demokomponenten
exempel/2 - demonstration av fastighetsförteckningsexpansion
exempel/3 - demonstration av att utöka listan över metoder
Varje katalog innehåller ett VS 2008-projekt och en färdig 1C-konfiguration.