webForumDet fria alternativet

SPCS API

.NETur .NET

65 svar · 15 186 visningar · startad av Zaiman · sida 3 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 feb. 20076 inlägg
#41

Zaiman,
Jag fick det att fungera tillslut. Det visade sig att jag hade fel returtyp. När jag deklarerade den som void så fungerade det galant (kunde ta bort [MarshalAs... biten också).

[Edit]
Glömde skriva att ADKERROR-parametern måste vara "ref" också
[/Edit]

Medlem sedan dec. 20014 239 inlägg
#42

ashen

Nice.. Nu får man en vettigare felhantering.

All kod som jag postade tidigare var inte korrekt men den gav ett hum om hur jag gjort. Ska korrigera den när det mesta är klart.

Har du lust får du gärna dela med dig av dina lösningar..

Medlem sedan feb. 20076 inlägg
#43

Nu har dock AdkClose börjat strula. Fram till dess fungerar allt, men när jag kör AdkClose får jag AccessViolation Exception. Får se om jag får till det. Här är min kod iaf.

[EDIT]
Det är bara när jag lekt med fakturor (som har rader) som adkClose inte fungerar. Kanske är någon struktur jag missat att ta bort eller så. Om jag lägger till en faktura utan rader fungerar det felfritt
[/EDIT]

[EDIT]
Ytterligare uppdatering. Det är när jag försöker lägga till artikelrader som det blir fel. Om artikeln finns så läggs fakturan till, men AdkClose() kastar exception. Om artikeln inte finns får jag exception redan vid AdkAdd(). Det blir också fel om fakturan redan finns (AdkClose() kastar exception då).
Koden för att kontrollera om artikeln finns är exakt samma som jag använder för kunder, men där fungerar det alltid... Antagligen är det något jag missar att sätta eller ta bort... Ska ringa Visma imorrn och fråga om de kan veta vad det beror på.
[/EDIT]

         // Ö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);

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

        // 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);

        //Återställ struktur
        [DllImport("adk.dll", EntryPoint = "_AdkResetStruct@4", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern ADKERROR AdkResetStruct(int pDb);

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

        // Radera
        [DllImport("adk.dll", EntryPoint = "_AdkDelete@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkDelete(int pDb);
        
        // Radera rad
        [DllImport("adk.dll", EntryPoint = "_AdkDeleteRow@8", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkDeleteRow(int pDb, int iIx);            
                
        // 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);

        // 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);

        //Föregående post
        [DllImport("adk.dll", EntryPoint = "_AdkPrevious@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkPrevious(int pDb);
         
        //Ställ på sista post i strukturen
        [DllImport("adk.dll", EntryPoint = "_AdkLast@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkLast(int pDb);

        //Sök upp en post
        [DllImport("adk.dll", EntryPoint = "_AdkFind@4", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkFind(int pDb);

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

        // Hämta bool
        [DllImport("adk.dll", EntryPoint = "_AdkGetBool@12", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkGetBool(int pDb, int iFieldID, ref int pbValue);

        // Hämta double
        [DllImport("adk.dll", EntryPoint = "_AdkGetDouble@12", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkGetDouble(int pDb, int iFieldID, ref double pdValue);

        public static double SPCSGetDouble(int pDb, int iFieldID)
        {
            double res = 0;
            SPCSTry(AdkGetDouble(pDb, iFieldID, ref res));
            return res;
        }

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

        public static string SPCSGetStr(int pDb, int iFieldID)
        {
            string result = string.Empty;
            SPCSTry(AdkGetStr(pDb, iFieldID, ref result, 256));
            return result;
        }

        //Hämta datum
        [DllImport("adk.dll", EntryPoint = "_AdkGetDate@12", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkGetDate(int pDb, int iFieldID, ref int pdaValue);

        //Hämta data
        [DllImport("adk.dll", EntryPoint = "_AdkGetData@16", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkGetData(int pDb, int iFieldID, int iIndex, ref int pDbRow);
        
         //Hämta decimaler
        [DllImport("adk.dll", EntryPoint = "_AdkGetDecimals@12", CharSet = CharSet.Ansi)]
        public static extern ADKERROR AdkGetDecimals(int pDb, int iFieldID, ref int iDec);

        //Hämta en feltext, behöver ev. vara unsafe
        [DllImport("adk.dll", EntryPoint = "_AdkGetErrorText@16", CharSet = CharSet.Ansi)]
        public static extern void AdkGetErrorText(ref ADKERROR err, int nErrorTextType, ref string achBuf, int ILen);
        
        //AdkSetBool
        [DllImport("adk.dll", EntryPoint = "_AdkSetBool@12", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkSetBool(int pDb, int iFieldId, int bValue);

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

        // AdkSetStr
        [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 = "_AdkSetDate@12", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkSetDate(int pDb, int iFieldId, int lValue);

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

        [DllImport("adk.dll", EntryPoint = "_AdkIsReadWrite@8", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern bool AdkIsReadWrite(int pDb, int iFieldId);

        [DllImport("adk.dll", EntryPoint = "_AdkLongToDate@12", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkLongToDate(int lValue, ref string _ppsValue, int Ilen);

        [DllImport("adk.dll", EntryPoint = "_AdkDateToLong@8", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkDateToLong(string sValue, ref int plValue);

        public static int SPCSDateToLong(DateTime date)
        {
            int ldate = 0;
            SPCSTry(AdkDateToLong(date.ToString(), ref ldate));
            return ldate;
        }

        [DllImport("adk.dll", EntryPoint = "_AdkGetType@12", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkGetType(int pDb, int iFieldId, ref ADK_FIELD_TYPE pType);

        [DllImport("adk.dll", EntryPoint = "_AdkGetLength@12", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkGetLength(int pDb, int iFieldId, ref int iLength);

        [DllImport("adk.dll", EntryPoint = "_AdkSetSortOrder@8", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkSetSortOrder(int pDb, ADK_SORT_ORDER iFieldId);

        [DllImport("adk.dll", EntryPoint = "_AdkGetFieldName@16", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern ADKERROR AdkGetFieldName(int IDataBaseId, int iFieldId, ref string ppsValue, int Ilen);

        public static string SPCSGetError(ADKERROR error, ADK_ERROR_TEXT_TYPE errorType)
        {
            string str = string.Empty;
            AdkGetErrorText(ref error, (int)errorType, ref str, 256);
            return str;
        }
    }
}
Medlem sedan dec. 20014 239 inlägg
#44

Hur gick det? Fick du något vettigt svar från Visma?

Har själv inte haft tid till att pula mer med detta projekt, andra har just nu högre prioritering.
Men jag följer tråden med spänning. Kul när det går framåt.

Medlem sedan feb. 20076 inlägg
#45

Det slutade med att jag fick maila kod till dem. Får väl se om jag får ett svar under veckan

Zaiman skrev:

Hur gick det? Fick du något vettigt svar från Visma?

Har själv inte haft tid till att pula mer med detta projekt, andra har just nu högre prioritering.
Men jag följer tråden med spänning. Kul när det går framåt.

Medlem sedan feb. 20076 inlägg
#46

Nu känner jag mig dum... Efter att ha tjatat lite på Visma kollade en av deras programmerare på min kod.

Det visade sig att om man inte fyller upp strängen till önskad längd innan anropet så försöker den deallokera minne man aldrig använt... alltså Exception!!! :P

Det värsta är att jag redan testat det här, men jag måste ha gjort fel nånstans då...

Jaja, nu fungerar allt iaf, så tack till Visma :)

public static string SPCSGetStr(int pDb, int iFieldID)
        {
            string result = new string(' ', 256);
            SPCSTry(AdkGetStr(pDb, iFieldID, ref result, 256));
            return result;
        }

        public static string SPCSGetError(ADKERROR error, ADK_ERROR_TEXT_TYPE errorType)
        {
            string str = new string(' ',256);
            AdkGetErrorText(ref error, (int)errorType, ref str, 256);
            return str;
        }
Medlem sedan mars 20071 inlägg
#47

Hej!

Någon som kan hjälpa mig att utveckla ett litet program för att importera kund samt skapa en order + orderrader knutet till den nyss skapade kunden.

Jag vill att den skall plocka informationen från en .txt fil eller liknande vars format ni kan få som ni vill.

T.ex
-----------------------
import.txt
-----------------------
Namn;Adress1;Postnr;Postort;Tel;Email;\n
Levsätt;Betsätt;\n
Artnr;Antal\n
Artnr;Antal\n
Artnr;Antal\n

Klart..

Kontakta mig snarast på thomas.andersson@gmail.com då det är ganska "akut".

Mot betalning såklart!

Medlem sedan juni 20073 inlägg
#48

Zaiman, tack för tipset om tråden... din kod ser riktigt intressant ut.

Inte möjligt att man kan få se mer av den? Känner att hjärnan fortfarande behöver lite skjuts innan den ska igår...

(o vissa dagar bara hatar man sitt jobb :))

Medlem sedan dec. 20014 239 inlägg
#49

Har inte haft tid att labba mer än det som finns här tyvärr. Så om du kommer framåt är jag intresserad av din kod och se hur du löser det.

Lycka till.

Medlem sedan feb. 20076 inlägg
#50

Nomaden, vad behöver du hjälp med? Jag fick min koppling att fungera utan bekymmer...

Kan dessvärre inte visa lägga ut koden eftersom den tillhör firman, men jag kan svara på frågor :)

Medlem sedan juni 20073 inlägg
#51

ashen skrev:

Nomaden, vad behöver du hjälp med? Jag fick min koppling att fungera utan bekymmer...

Kan dessvärre inte visa lägga ut koden eftersom den tillhör firman, men jag kan svara på frågor :)

Jag är ingen höjdare på .Net över huvud taget om vi säger så... så det jag skulle behöva hjälp med är hur jag ska strukturera applikationen för att kunna använda adk.dll - hur den importeras etc. Allt jag gjort såhär långt resulterar bara i en massa felmeddelanden.. ^^

Vill helst göra något som fungerar direkt med asp.net då det är en webbapp som i slutändan ska kopplas till spcs...

Medlem sedan maj 20072 inlägg
#52

Är det någon som vet hur man använder AdkSetWarningFunction

Medlem sedan juni 20076 inlägg
#53

Hur koppla .NET med adk.dll?

Hej!

Är nybörjare på det här med SPCS-integration, men jag behöver skriva ett program i .NET som kan lägga in, ta bort, och lista fakturor i SPCS Administration. Jag har SPCS utvecklarpaket och vill använda adk.dll.

Tyvärr verkar inte SPCS ha någon dokumentation för hur man kopplar ihop .NET och adk.dll. Jag har försökt mig på att testa er exempelkod, men den kompilerar inte, främst pga. konstanter som t.ex. ADK_DB_INVOICE_HEAD, som kompilatorn inte kan hitta. Jag verkar sakna något namespace eller liknande.

Är det någon som har lust att posta ett minimalt, men kompilerande program i C# eller VB.NET, som interagerar med t.ex. Övningsbolaget AB? Vore mycket tacksam!

Medlem sedan dec. 20014 239 inlägg
#54

Alla konstanter finns i det packet du fått av SPCS. Har för mig att dem ligger i ADK.LIB i C varianten.

Medlem sedan juni 20076 inlägg
#55

Tackar

Hej, tack för hjälpen, nu fungerar det! :)

Som hjälp till andra: Ni kanske måste byta ut sökvägen syspath till

string syspath = "C:\\Documents and Settings\\All Users\\Application Data\\SPCS\\SPCS Administration\\Gemensamma filer";

om ni gör en standardinstallation av SPCS. Jag fick det kryptiska felkod 137 i err.lRc, men lyckades luska ut vad felet var efter att ha kollat i manualen.

Medlem sedan juni 20076 inlägg
#56

Hur lägga till faktura med valfritt artikelnummer?

Hej!

Skulle vilja lägga till fakturor där artikelnummer kan vara godtycklig sträng, t.ex. "Hejsan Pelle", men API:et verkar kräva att strängen finns inlagd som artikelnummer för en artikel. Jag får värdet error.lRc = 50 (Kan ej hitta angiven artikel). Således måste jag först skapa en artikel som har artikelnumret "Hejsan Pelle", men detta vill jag undvika.

Det går att använda godtyckliga artikelnummer som inte är inlagda om man använder gränssnittet till SPCS Administration 1000 (om än med ett varningsmeddelande), men om det går med API:et verkar mer tveksamt. Någon som vet något om detta? Finns det något API-anrop som jag missat? :q

Min nuvarande kod för att lägga in en faktura (fungerar när artikelnumret är känt) är:

pData = AdkCreateData(ADK_DB_INVOICE_HEAD);
error = AdkSetStr(pData, ADK_OOI_HEAD_CUSTOMER_NUMBER, customerNumber.ToString());
error = AdkSetStr(pData, ADK_OOI_HEAD_TYPE_OF_INVOICE, "F");
pDataRow = AdkCreateDataRow(ADK_DB_INVOICE_ROW, 1);
[red][B]error = AdkSetStr(pDataTemp, ADK_OOI_ROW_ARTICLE_NUMBER, articleNumber);[/B][/red]
error = AdkSetDouble(pDataTemp, ADK_OOI_ROW_QUANTITY2, 1);
error = AdkSetData(pData, ADK_OOI_HEAD_ROWS, pDataRow);
error = AdkSetDouble(pData, ADK_OOI_HEAD_NROWS, 1);
error = AdkAdd(pData);
error = AdkDeleteStruct(pData);
Medlem sedan juni 20076 inlägg
#57

Hur radera faktura?

Jag gav upp att försöka lägga in godtyckliga artikelnummer, det verkar inte gå. x(

Nu är mitt senaste problem att jag inte kan radera en inlagd faktura... :x

Jag vet inte om man först måste radera alla poster i en faktura för att kunna radera den, men även om jag gör det får jag fel 164 (icke raderbar) när jag försöker radera med följande kod:

        public void DeleteInvoice(string invoiceID)
        {
            OpenConnection();
            try
            {
                int pData = AdkCreateData(ADK_DB_INVOICE_HEAD);
                AdkError error = AdkSetDouble(pData, ADK_OOI_HEAD_DOCUMENT_NUMBER, double.Parse(invoiceID));
                ErrorCheck(error);
               [red] error = AdkDelete(pData);[/red] // Skapar fel 164   :bla   :bla   :bla 
                ErrorCheck(error);
                error = AdkDeleteStruct(pData);
                ErrorCheck(error);
            }
            finally
            {
                CloseConnection();
            }
        }

Uppenbarligen har jag felaktig kod. Någon som kan hjälpa?

Medlem sedan dec. 20014 239 inlägg
#58

Normalt sett kan man inte kunna radera fakturor. Du borde kunna sätta den till Makulerad istället.

Medlem sedan juni 20076 inlägg
#59

Makulering av faktura

Hej, tack för tipset! :i Nu kan jag, med koden nedan, ange att en faktura ska makuleras. En grej jag missade var att man måste anropa AdkUpdate() för att uppdateringen ska slå igenom. SPCS dokumentation nämner inte vilka heltal som svarar mot sant och falskt, men 1 respektive 0 verkar fungera.

        public void CancelInvoice(double invoiceID)
        {
            OpenSpcsConnection();
            try
            {
                int pData = AdkCreateData(ADK_DB_INVOICE_HEAD);
                AdkError error = AdkSetDouble(pData, ADK_OOI_HEAD_DOCUMENT_NUMBER, invoiceID);
                ErrorCheck(error);
                error = AdkSetBool(pData, ADK_OOI_HEAD_DOCUMENT_CANCELLED, 1);
                ErrorCheck(error);
                [red]error = AdkUpdate(pData);[/red]
                ErrorCheck(error);
                error = AdkDeleteStruct(pData);
                ErrorCheck(error);
            }
            finally
            {
                CloseSpcsConnection();
            }
        }
Medlem sedan dec. 20014 239 inlägg
#60

Dompan skrev:

Hej, tack för tipset! :i Nu kan jag, med koden nedan, ange att en faktura ska makuleras. En grej jag missade var att man måste anropa AdkUpdate() för att uppdateringen ska slå igenom. SPCS dokumentation nämner inte vilka heltal som svarar mot sant och falskt, men 1 respektive 0 verkar fungera.

        public void CancelInvoice(double invoiceID)
        {
            OpenSpcsConnection();
            try
            {
                int pData = AdkCreateData(ADK_DB_INVOICE_HEAD);
                AdkError error = AdkSetDouble(pData, ADK_OOI_HEAD_DOCUMENT_NUMBER, invoiceID);
                ErrorCheck(error);
                error = AdkSetBool(pData, ADK_OOI_HEAD_DOCUMENT_CANCELLED, 1);
                ErrorCheck(error);
                [red]error = AdkUpdate(pData);[/red]
                ErrorCheck(error);
                error = AdkDeleteStruct(pData);
                ErrorCheck(error);
            }
            finally
            {
                CloseSpcsConnection();
            }
        }

Hallå i tråden...

Dompan, hur har det gått för dig? *nyfiken*
Själv har arbetet legat nere på SPCS Api fronten. Har haft mycket annat att göra och det har fått stryka på foten tyvärr.
Men nu är det dags att sätta sig in i det igen. Dags för nya tag igen :)

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