webForumDet fria alternativet

SPCS API

.NETur .NET

65 svar · 15 186 visningar · startad av Zaiman · sida 2 av 4

Frågan, av Zaiman

Någon som har exempelkod för att använda SPCS API i C# ? Helst någon som gjort anrop på api med orderläggning, bara något enkelt så att jag kommer igång och lär mig. :bire

Läs frågan i sin helhet →
Medlem sedan nov. 20065 inlägg
#21

Zaiman: Du har fått mail.

OveRRidE: Jo, det är så jag gör nu, men det blir en massa onödig overhead som slöar ner programmet. De kunde ju släppa samma API som de själva använder, vad är de rädda för att man ska göra ett nytt SPCS 2000 ADM ? Skulle man det skulle man knappast använda deras keffa egenhändigt gjorda databaser.

Medlem sedan nov. 20065 inlägg
#22

Aleborg, har du några specs alt. kod för att jobba direkt mot databaserna som du kan känner för att dela med dig ?

Inte nog med att det API de säljer kostar pengar, så är det faktiskt inte adekvat nog att använda i produktion. Skulle gärna utveckla ett nytt API, och då släppa det under GPL eller BSD. Till att börja med iaf undersöka vad det skulle kunna innebära i tid.

API:et skulle vara OS-oberoende (kunna kompileras för flera olika OS). Saknad funktionalitet implementeras (t.ex. sökning/villkor för alla kolumner i en tabell). Det skall naturligtvis vara lika säkert att använda i produktion som deras egna API.

Är någon sugen på att hjälpa till ? Hör av er till mig isf.
Kan tänka mig att Visma inte klappar i sina händer om man skulle göra verklighet av ett sådant här projekt, men jag tvivlar på att de kan göra mycket åt saken. Skulle de kunna det skulle vi t.ex. inte ha projekt som Samba mm.

Medlem sedan feb. 200112 078 inlägg
#23

Nevyn skrev:

OveRRidE: Jo, det är så jag gör nu, men det blir en massa onödig overhead som slöar ner programmet. De kunde ju släppa samma API som de själva använder, vad är de rädda för att man ska göra ett nytt SPCS 2000 ADM ? Skulle man det skulle man knappast använda deras keffa egenhändigt gjorda databaser.

Vad är det som säger att de inte själva gör så? ;)

Medlem sedan nov. 20065 inlägg
#24

Override, haha ja. Fast det verkar som om den ligger och läser av databaserna, exempelvis Ordertabellen (om man är inne på ordrar) så fort den ändras, och detta går snabbt, bra mycket snabbare än om jag i mitt program går igenom orderraderna.

F.ö. är databaserna FoxBase+/dBASE III+, de sägs däremot modifierat indexformatet något.

Med detta program http://dbf.berlios.de/ kan jag på min BSD-burk läsa ut och konvertera informationen i .DBF filerna till SQL. Den skall även kunna skriva till DBF filerna, men detta har jag inte testat.

Skulle vara intressant och veta hur låsningen fungerar, utan det skulle jag inte våga mig på att göra en mjukvara som skriver till databaserna.

Sen har jag ingen erfarenhet av FoxPro och dBase, kul att de iaf använder en del av en standard.

EDIT: En liten test, att konvertera en orderdatabas med drygt 4000 poster till SQL-satser tog ~100ms.

Medlem sedan dec. 20014 239 inlägg
#25

När jag använde asp 3.0 så använde jag mig av Foxpros OLE driver och körde "vanlig" SQL fråga mot databaserna. Iof så hämtade jag bara data.
Även nu har jag ett jobb som går och hämtar data från databaserna direkt och för över det till en SQL databas.

Ska leta på lite kod att dela med mig av om ni är intresserade?

Nevyn:
Intresserad är jag men jag har inte så hög kompetens då jag är ganska mycket nybörjare. Men jag lär mig varefter och är mycket nyfiken av mig :)

Medlem sedan sep. 2005114 inlägg
#26

SPCS får mina öron att blöda. Bara orden.

I vilket fall så är du rätt så out of options när det kommer till att selektera ut saker som inte täcks av API:et som standard. Tyvärr är nog filtrering din enda riktiga möjlighet där.. Jag har hört med Visma om det, och dom har själva skickat mig exempelkod på korrekt sätt att göra det.. Vilket är att dra igenom alla rader och leta efter vad du ska hitta. Fult, långsamt, but I guess it gets the job done.

Tar nog en 10-15 minuter för mitt program att köra en veva där den söker genom 1000 bokningsrader på 5000 artiklar..

Medlem sedan nov. 20065 inlägg
#27

Zaiman, ja gärna.

Dapper, haha, själv blöder jag i hjärnan. När man bara vet att körningstiden från 10-15 min (ungefär samma för mitt), (jämför cirka 5000 ordrar mot ett annat system och uppdaterar/lägger till nya ordrar så att datat matchar), skulle med enkla medel kunna kortast ner iaf till 1 minut.

Klart, 10-15 minuter är bättre än göra det manuellt, men det stör mig nåt så oerhört att behöva lämna ifrån mig en sådan mjukvara.

Medlem sedan dec. 20014 239 inlägg
#28

Gammal kodsnutt mot databaser direkt

idnr = Request.Form("idnr")
Set db = Server.CreateObject("ADODB.Connection")
strConn = "Provider=vfpoledb.1;Data Source=C:\btvdb\;Collating Sequence=general"
	db.Open(strConn)
	SQL = "SELECT BENAEMN,PRIS,ILAGER,RESANT,ANM1,ART.ARTNR, PRIS.ARTNR FROM ART LEFT OUTER JOIN PRIS ON ART.ARTNR = PRIS.ARTNR WHERE ART.ARTGRP = '" & idnr &"' AND PRIS.PRISL = '1' AND PRIS >0"

Set rs = db.Execute(SQL)

Oj inser att det var länge sedan jag gjorde den där koden. Men den visar lite enkelt hur jag gjorde på den tiden iaf. I katalogen hade jag placerat endast de databaser jag behövde men det kan lika gärna vara hela företagskatalogen med alla databaser.

Sedan var det bara att iterera ut det man fick i recordsettet. Detta sätt kombinade jag för att snabbare söka efter artiklar i registret. Att söka i direkt i spcsprogrammet var mycket krångligare och tog längre tid.

Tillägg:
Observera att jag använde mig av OLE Drivern för Foxpro.

Medlem sedan dec. 20014 239 inlägg
#29

dapper skrev:

SPCS får mina öron att blöda. Bara orden.

Jag har hört med Visma om det, och dom har själva skickat mig exempelkod på korrekt sätt att göra det..

Den exempelkoden är vi mycket nyfikna på... ;)

Ju mer jag hör om SPCS API desto mer vill jag bara lägga mitt projekt åt sidan och inte lära mig det :l

Medlem sedan juli 200012 978 inlägg
#30

Grattulerar till insikten. Vad var det jag skrev i andra inlägget?

Medlem sedan dec. 20014 239 inlägg
#31

Hmm.. jo.. men ibland har man ju inget val.

Medlem sedan apr. 2003115 inlägg
#32

Kom ni fram till någon lösning för att importera ordrar ifrån ett websystem till era bokföringsprogram för att skapa fakturaunderlag.

Några bra förslag på alternativ till spcs? har kollat på många, men alla verkar ha stora problem med att importera dessa uppgifter!?

Hittade denna länken till mamut där man använder sie för att importera ordrar. Men har inte provat om spcs stödjer det!?

ftp://dl.mamut.com/download/mbs/doc/Mamut_Import_Export_se.pdf

/fredrik

Medlem sedan feb. 2003216 inlägg
#33

Jag har bråkat mycket med SPCS APIet och kan bara hålla med om vad som skrivits ovan om dess funktionalitet.

Jag har skrivit alla mina metoder i C++ och det fungerar väl hyffsat. Dock saknar man ju en hel del felhantering från APIet. Varför inte slänga exceptions istället för att använda sin egen specialfelhantering?!

Min applikation fungerar så här i stora drag:
1. Anropar en server som kopplar mot SPCS APIet genom socket med PHP.
2. Servern utför önskad funktion på SPCS.
3. Servern skickar tillbaka svar till PHP genom socket
4. PHP behandlar datan på önskat sätt.

Nevyn: Det går att söka fram data på olika fält, dock lite begränsat. Du använder en metod för att sätta sorteringsordningen. Kommer inte ihåg vad den heter nu och jag är inte på jobbet så jag kan inte kolla upp det, men det finns. Kolla i din API-specifikation

turbofreddan: Jag gör på följande sätt:
1. Skapa en ny order i SPCS via APIet.
2. Fyll i relevant data (Börja med kund för att slippa problem med satta priser osv.)
Det borde räcka för att man skall kunna fakturera ordern.

Medlem sedan apr. 2003115 inlägg
#34

Tack,

Medlem sedan dec. 20014 239 inlägg
#35

Nevyn:

Blev det något projekt av eller är det bara att lägga ned?

Har gjort en liten .asp sida som gör en fritextsökning och listar vilka dokument som är kopplade till resultatet av sökningen. Mycket smidigt när man letar tex serienummer på inköpta saker.

Medlem sedan feb. 20013 023 inlägg
#36

Anmäler intresse av att hjälpa till med ett nytt SPCS-API. :)

Medlem sedan dec. 20014 239 inlägg
#37

Meddelande:

Har nu lyckats klura ut hur jag skapar en faktura med SPCS API och .NET (C#).

Här kommer del av koden:


        // Öppna företag räkna ned användarlicenser
        [DllImport("adk.dll", EntryPoint = "_AdkOpen@8", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkOpen(string sysPath, string ftgPath);

        // Skapa en struktur
        [DllImport("adk.dll", EntryPoint = "_AdkCreateData@4", CharSet = CharSet.Ansi)]
        public static extern int AdkCreateData(int IDataBaseId);

        // Uppdatera
        [DllImport("adk.dll", EntryPoint = "_AdkUpdate@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkUpdate(int pDb);

        //Stäng företag räkna upp användarlicenser
        [DllImport("adk.dll", EntryPoint = "_AdkClose@0", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkClose();

        // Radera struktur
        [DllImport("adk.dll", EntryPoint = "_AdkDeleteStruct@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkDeleteStruct(int pDb);

        // Ställ på första post i strukturen
        [DllImport("adk.dll", EntryPoint = "_AdkFirst@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkFirst(int pDb);

        // Nästa post
        [DllImport("adk.dll", EntryPoint = "_AdkNext@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkNext(int pDb);

        // Lägg till
        [DllImport("adk.dll", EntryPoint = "_AdkAdd@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkAdd(int pDb);

        // Hämta sträng
        [DllImport("adk.dll", EntryPoint = "_AdkGetStr@16", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkGetStr(int pDb, int iFieldID, string ppsValue, int iLen);

        // Skapa en datarad
        [DllImport("adk.dll", EntryPoint = "_AdkCreateDataRow@8", CharSet = CharSet.Ansi)]
        public static extern int AdkCreateDataRow(int IDataBaseId, int iNumber);

        // Hämta en datarad
        [DllImport("adk.dll", EntryPoint = "_AdkGetDataRow@8", CharSet = CharSet.Ansi)]
        public static extern int AdkGetDataRow(int pDB, int iIndex);

        //Hämta en feltext
        [DllImport("adk.dll", EntryPoint = "_AdkGetErrorText@16", CharSet = CharSet.Ansi)]
        unsafe public static extern ADKERROR AdkGetErrorText(int err, int nErrorTextType, [MarshalAs(UnmanagedType.LPStr)]ref StringBuilder achBuf, int ILen);

        [DllImport("adk.dll", EntryPoint = "_AdkSetDouble@16", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        unsafe public static extern ADKERROR AdkSetDouble(int pDb, int iFieldId, double dValue);

        [DllImport("adk.dll", EntryPoint = "_AdkDeleteRow@8", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        unsafe public static extern ADKERROR AdkDeleteRow(int pDb, int iIx);
        
        // AdkSetStr
        [System.Runtime.InteropServices.DllImport("adk.dll", EntryPoint = "_AdkSetStr@12", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkSetStr(int pDb, int iFieldId, string pValue);

        [DllImport("adk.dll", EntryPoint = "_AdkSetData@12", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        unsafe public static extern ADKERROR AdkSetData(int pDb, int iIx, int pDataRow);
         
       
        
	

        public struct ADKERROR
        {

            public int lRc;
            public int lDbTable;
            public int lField;
            public int lFunction;
            public int lProgramPart;

        }

        private void button1_Click(object sender, EventArgs e)
        {
            string ftgpath = "C:\\Program Files\\SPCS\\SPCS Administration\\Ovnbol";
            string syspath = "C:\\Program Files\\SPCS\\SPCS Administration";
            ADKERROR err = new ADKERROR();
            err = AdkOpen(syspath, ftgpath);
            if (err.lRc != 0)
            {
                textBox1.Text = "Fel vid öppning av SPCS";
            }
            else
            {
                textBox1.Text = "Spcs öppnade " + ftgpath;
            }

           int  pData;
            pData = AdkCreateData(ADK_DB_INVOICE_HEAD);
           
            textBox1.Text += "\r\n" + pData.ToString();
            err = AdkSetStr(pData, ADK_OOI_HEAD_CUSTOMER_NUMBER, "104");
            err = AdkSetStr(pData, ADK_OOI_HEAD_TYPE_OF_INVOICE, "F");
            int pDataRow;
            pDataRow = AdkCreateDataRow(ADK_DB_INVOICE_ROW, 1);
            int pDataTemp;
            pDataTemp = AdkGetDataRow(pDataRow, 0);
            err = AdkSetStr(pDataTemp, ADK_OOI_ROW_ARTICLE_NUMBER, "112");
            err = AdkSetDouble(pDataTemp, ADK_OOI_ROW_QUANTITY2, 40);
            err = AdkSetDouble(pDataTemp, ADK_OOI_ROW_QUANTITY1, 40);

            err = AdkSetData(pData, ADK_OOI_HEAD_ROWS, pDataRow);
            err = AdkSetDouble(pData, ADK_OOI_HEAD_NROWS, 1);
            err = AdkAdd(pData);

            err = AdkDeleteStruct(pData);

           

        }

Skam den som ger sig... Eller Trägen vinner

Ja ja kanske inte den snyggaste lösningen, men det fungerar. Felhantering och sådant ska naturligtvis till. Men så här långt fungerar det iaf.

Medlem sedan feb. 20076 inlägg
#38

Hej alla (första posten),

Jag har fått till något motsvarande. Det fungerar fint ända tills jag ska hämta ut en feltext. Jag får accessviolation exception då. Utan pardon. Min egen variant ser ut så här

public static extern ADKERROR AdkGetErrorText([MarshalAs(UnmanagedType.Struct)]ADKERROR err, int nErrorTextType, ref string achBuf, int ILen);

Den fungerar inte, och det gör dessvärre inte Zaimans heller. Samma fel då också...

Jag antar att det har med ADKERROR att göra, men å andra sidan fungerar det inte (för mig) att köra med en int, som Zaiman gör. Någon som har nåt förslag? Får jag det att fungera kan jag posta min kod här.

Zaiman skrev:

Meddelande:

Har nu lyckats klura ut hur jag skapar en faktura med SPCS API och .NET (C#).

Här kommer del av koden:


        // Öppna företag räkna ned användarlicenser
        [DllImport("adk.dll", EntryPoint = "_AdkOpen@8", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkOpen(string sysPath, string ftgPath);

        // Skapa en struktur
        [DllImport("adk.dll", EntryPoint = "_AdkCreateData@4", CharSet = CharSet.Ansi)]
        public static extern int AdkCreateData(int IDataBaseId);

        // Uppdatera
        [DllImport("adk.dll", EntryPoint = "_AdkUpdate@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkUpdate(int pDb);

        //Stäng företag räkna upp användarlicenser
        [DllImport("adk.dll", EntryPoint = "_AdkClose@0", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkClose();

        // Radera struktur
        [DllImport("adk.dll", EntryPoint = "_AdkDeleteStruct@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkDeleteStruct(int pDb);

        // Ställ på första post i strukturen
        [DllImport("adk.dll", EntryPoint = "_AdkFirst@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkFirst(int pDb);

        // Nästa post
        [DllImport("adk.dll", EntryPoint = "_AdkNext@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkNext(int pDb);

        // Lägg till
        [DllImport("adk.dll", EntryPoint = "_AdkAdd@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkAdd(int pDb);

        // Hämta sträng
        [DllImport("adk.dll", EntryPoint = "_AdkGetStr@16", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkGetStr(int pDb, int iFieldID, string ppsValue, int iLen);

        // Skapa en datarad
        [DllImport("adk.dll", EntryPoint = "_AdkCreateDataRow@8", CharSet = CharSet.Ansi)]
        public static extern int AdkCreateDataRow(int IDataBaseId, int iNumber);

        // Hämta en datarad
        [DllImport("adk.dll", EntryPoint = "_AdkGetDataRow@8", CharSet = CharSet.Ansi)]
        public static extern int AdkGetDataRow(int pDB, int iIndex);

        //Hämta en feltext
        [DllImport("adk.dll", EntryPoint = "_AdkGetErrorText@16", CharSet = CharSet.Ansi)]
        unsafe public static extern ADKERROR AdkGetErrorText(int err, int nErrorTextType, [MarshalAs(UnmanagedType.LPStr)]ref StringBuilder achBuf, int ILen);

        [DllImport("adk.dll", EntryPoint = "_AdkSetDouble@16", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        unsafe public static extern ADKERROR AdkSetDouble(int pDb, int iFieldId, double dValue);

        [DllImport("adk.dll", EntryPoint = "_AdkDeleteRow@8", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        unsafe public static extern ADKERROR AdkDeleteRow(int pDb, int iIx);
        
        // AdkSetStr
        [System.Runtime.InteropServices.DllImport("adk.dll", EntryPoint = "_AdkSetStr@12", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkSetStr(int pDb, int iFieldId, string pValue);

        [DllImport("adk.dll", EntryPoint = "_AdkSetData@12", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        unsafe public static extern ADKERROR AdkSetData(int pDb, int iIx, int pDataRow);
         
       
        
	


        public struct ADKERROR
        {

            public int lRc;
            public int lDbTable;
            public int lField;
            public int lFunction;
            public int lProgramPart;


        }

        private void button1_Click(object sender, EventArgs e)
        {
            string ftgpath = "C:\\Program Files\\SPCS\\SPCS Administration\\Ovnbol";
            string syspath = "C:\\Program Files\\SPCS\\SPCS Administration";
            ADKERROR err = new ADKERROR();
            err = AdkOpen(syspath, ftgpath);
            if (err.lRc != 0)
            {
                textBox1.Text = "Fel vid öppning av SPCS";
            }
            else
            {
                textBox1.Text = "Spcs öppnade " + ftgpath;
            }

           int  pData;
            pData = AdkCreateData(ADK_DB_INVOICE_HEAD);
           
            textBox1.Text += "\r\n" + pData.ToString();
            err = AdkSetStr(pData, ADK_OOI_HEAD_CUSTOMER_NUMBER, "104");
            err = AdkSetStr(pData, ADK_OOI_HEAD_TYPE_OF_INVOICE, "F");
            int pDataRow;
            pDataRow = AdkCreateDataRow(ADK_DB_INVOICE_ROW, 1);
            int pDataTemp;
            pDataTemp = AdkGetDataRow(pDataRow, 0);
            err = AdkSetStr(pDataTemp, ADK_OOI_ROW_ARTICLE_NUMBER, "112");
            err = AdkSetDouble(pDataTemp, ADK_OOI_ROW_QUANTITY2, 40);
            err = AdkSetDouble(pDataTemp, ADK_OOI_ROW_QUANTITY1, 40);

            err = AdkSetData(pData, ADK_OOI_HEAD_ROWS, pDataRow);
            err = AdkSetDouble(pData, ADK_OOI_HEAD_NROWS, 1);
            err = AdkAdd(pData);

            err = AdkDeleteStruct(pData);

           

        }

Skam den som ger sig... Eller Trägen vinner

Ja ja kanske inte den snyggaste lösningen, men det fungerar. Felhantering och sådant ska naturligtvis till. Men så här långt fungerar det iaf.

Medlem sedan apr. 2003115 inlägg
#39

Hej alla, såg att någon svarat mitt gamla inlägg, nästan glömt bort den här tråden, jag bytte iallafall till vismaxor istället, funkar kanon. Där kan jag pilla i databasen som jag vill :)

Medlem sedan dec. 20014 239 inlägg
#40

ashen:
Välkommen till webforum.
Om du får din ADKERROR att fungera med att få ut feltext kan du väl meddela antingen här eller mig direkt. Har inte fått allt att fungera heller än. Bara lyckats skapa faktura eller order så här långt.

144 ms totalt · 3 externa anrop · v20260731065814-full.b746b907
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
142 ms — hämta tråd, inlägg och bilagor (db)