anaf efactura generare token cu citire automata token din romfast.ro
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -500,21 +500,200 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
|||||||
Endproc && SaveToken
|
Endproc && SaveToken
|
||||||
|
|
||||||
|
|
||||||
|
*!* 07.07.2026
|
||||||
|
*!* newToken - flux automat OAuth2: state + sesiune PHP + polling pick.php
|
||||||
|
*!* implementare unica in AnafeFacturaServer; ANAFeFactura deleaga
|
||||||
|
*!* kill switch ANAF_TOKEN_AUTOFLOW (1=automat, 0=vechi), garda headless
|
||||||
|
|
||||||
* Intoarce tokenul de acces la ANAF (eFactura) daca este salvat sau obtine un nou token
|
* Intoarce tokenul de acces la ANAF (eFactura) daca este salvat sau obtine un nou token
|
||||||
* Se apeleaza din formularul anaf_token.do_executa
|
* Se apeleaza din formularul anaf_token.do_executa (prin ANAFeFactura.newToken)
|
||||||
Function newToken
|
Function newToken
|
||||||
Local lcTokenURL
|
LOCAL lnAutoFlowVal, lcAutoFlowStr, lcTokenURL, lcState, lcStatePrefix
|
||||||
|
LOCAL lcBuf1, lcBuf2, lni, lnAscByte, lcHexChars
|
||||||
|
LOCAL lcBrowserUrl, lcPickUrl, lcExitCode
|
||||||
|
LOCAL loHTTP, lnStatus, lcResponse, loJson
|
||||||
|
LOCAL lnStartSec, lnElapsed, lnStep, lnKey
|
||||||
|
LOCAL loExHTTP, loExJson, loExSave
|
||||||
|
|
||||||
This.Log('Introduceti in calculator tokenul USB cu semnatura electronica' + LF + ;
|
* --- Garda headless: server/ROAEFACTURA (lServer=.T.) sau _SCREEN invizibil ---
|
||||||
'Se va deschide pagina ANAF de generare token. Introduceti PIN-ul pentru semnatura electronica.' + LF + ;
|
* Pastreaza EXACT comportamentul vechi al AnafeFacturaServer.newToken
|
||||||
'Copiati codurile "Token" si "Refresh Token" afisate si completati-le in ' + m.gcGeneralIniFile)
|
IF This.lServer OR !_SCREEN.Visible
|
||||||
|
This.Log('Introduceti in calculator tokenul USB cu semnatura electronica' + LF + ;
|
||||||
|
'Se va deschide pagina ANAF de generare token. Introduceti PIN-ul pentru semnatura electronica.' + LF + ;
|
||||||
|
'Copiati codurile "Token" si "Refresh Token" afisate si completati-le in ' + m.gcGeneralIniFile)
|
||||||
|
lcTokenURL = This.cTokenUrl
|
||||||
|
open_default_app(m.gcGeneralIniFile)
|
||||||
|
open_default_app(m.lcTokenURL)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
lcTokenURL = This.cTokenUrl
|
* --- Kill switch: default 1 la NULL/inexistent/Oracle indisponibil ---
|
||||||
|
lnAutoFlowVal = 1
|
||||||
|
TRY
|
||||||
|
lcAutoFlowStr = ALLTRIM(NVL(citeste_optiune("ANAF_TOKEN_AUTOFLOW"), ''))
|
||||||
|
IF !EMPTY(lcAutoFlowStr)
|
||||||
|
lnAutoFlowVal = INT(VAL(lcAutoFlowStr))
|
||||||
|
ENDIF
|
||||||
|
CATCH
|
||||||
|
lnAutoFlowVal = 1
|
||||||
|
ENDTRY
|
||||||
|
|
||||||
open_default_app(m.gcGeneralIniFile)
|
lcTokenURL = ALLTRIM(NVL(This.cTokenUrl, ''))
|
||||||
open_default_app(m.lcTokenURL)
|
IF EMPTY(lcTokenURL)
|
||||||
|
lcTokenURL = 'https://romfast.ro/oauth2/'
|
||||||
|
ENDIF
|
||||||
|
|
||||||
Endfunc
|
* --- Kill switch OFF (0) -> comportament vechi nemodificat ---
|
||||||
|
IF lnAutoFlowVal <> 1
|
||||||
|
AMESSAGEBOX('Introduceti in calculator tokenul USB cu semnatura electronica' + CHR(13) + CHR(10) + ;
|
||||||
|
'Se va deschide pagina ANAF de generare token. Introduceti PIN-ul pentru semnatura electronica.' + CHR(13) + CHR(10) + ;
|
||||||
|
'Copiati codurile "Token" si "Refresh Token" afisate si completati-le in ROA.', 0 + 64, _Screen.Caption)
|
||||||
|
open_default_app(m.lcTokenURL)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
* --- Modal initial OK/Anulare ---
|
||||||
|
IF aMESSAGEBOX('Se va genera un token nou eFactura.' + CHR(13) + ;
|
||||||
|
'1. Introduceti tokenul USB cu semnatura electronica in calculator.' + CHR(13) + ;
|
||||||
|
'2. Se va deschide pagina ANAF in browser: selectati certificatul dvs. si introduceti PIN-ul.' + CHR(13) + ;
|
||||||
|
'3. Reveniti in aplicatie - tokenul se preia automat.' + CHR(13) + CHR(13) + ;
|
||||||
|
'Continuati?', 1 + 64, _Screen.Caption) <> 1
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF RIGHT(lcTokenURL, 1) <> '/'
|
||||||
|
lcTokenURL = lcTokenURL + '/'
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
* --- State anti-CSRF: 2 GUID-uri CoCreateGuid -> 64 hex (SYS(2015) e predictibil) ---
|
||||||
|
TRY
|
||||||
|
DECLARE INTEGER CoCreateGuid IN ole32 STRING @pguid
|
||||||
|
CATCH
|
||||||
|
* deja declarata in aceasta sesiune VFP
|
||||||
|
ENDTRY
|
||||||
|
lcBuf1 = REPLICATE(CHR(0), 16)
|
||||||
|
lcBuf2 = REPLICATE(CHR(0), 16)
|
||||||
|
CoCreateGuid(@lcBuf1)
|
||||||
|
CoCreateGuid(@lcBuf2)
|
||||||
|
lcBuf1 = lcBuf1 + lcBuf2 && 32 octeti aleatori = 256 biti entropie
|
||||||
|
lcHexChars = '0123456789abcdef'
|
||||||
|
lcState = ''
|
||||||
|
FOR lni = 1 TO 32
|
||||||
|
lnAscByte = ASC(SUBSTR(lcBuf1, lni, 1))
|
||||||
|
lcState = lcState + SUBSTR(lcHexChars, INT(lnAscByte/16)+1, 1) + SUBSTR(lcHexChars, MOD(lnAscByte,16)+1, 1)
|
||||||
|
ENDFOR
|
||||||
|
lcStatePrefix = LEFT(lcState, 8) && doar prefixul apare in log, niciodata tokenuri
|
||||||
|
|
||||||
|
lcBrowserUrl = lcTokenURL + '?state=' + lcState
|
||||||
|
lcPickUrl = lcTokenURL + 'pick.php'
|
||||||
|
This.Log('[' + lcStatePrefix + '] start flux automat token')
|
||||||
|
|
||||||
|
* --- Lansare browser; open_default_app (oexport.prg) intoarce .T./.F. (ShellExecute > 32) ---
|
||||||
|
IF !open_default_app(lcBrowserUrl)
|
||||||
|
AMESSAGEBOX('Nu s-a putut deschide browserul. Se continua cu fluxul manual: se va deschide pagina care afiseaza codurile pentru copiere.', 0 + 64, _Screen.Caption)
|
||||||
|
This.Log('[' + lcStatePrefix + '] esec lansare browser -> fallback manual')
|
||||||
|
open_default_app(lcTokenURL) && fara ?state -> pagina afiseaza codurile (retro-compat)
|
||||||
|
RETURN
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
* --- Polling pick.php la 2s: timeout 10 minute, Esc = anulare ---
|
||||||
|
lcExitCode = ''
|
||||||
|
lnStartSec = SECONDS()
|
||||||
|
DO WHILE .T.
|
||||||
|
lnElapsed = SECONDS() - lnStartSec
|
||||||
|
IF lnElapsed < 0
|
||||||
|
lnElapsed = lnElapsed + 86400 && trecere miezul noptii
|
||||||
|
ENDIF
|
||||||
|
IF lnElapsed >= 600
|
||||||
|
lcExitCode = 'timeout'
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
WAIT WINDOW 'Asteptare autorizare ANAF... Continuati in fereastra browserului: selectati certificatul si introduceti PIN-ul. (Esc = anulare)' NOWAIT
|
||||||
|
|
||||||
|
lnStatus = 0
|
||||||
|
lcResponse = ''
|
||||||
|
TRY
|
||||||
|
loHTTP = CREATEOBJECT('WinHttp.WinHttpRequest.5.1')
|
||||||
|
loHTTP.SetTimeouts(5000, 5000, 5000, 5000)
|
||||||
|
loHTTP.Open('POST', lcPickUrl, .F.)
|
||||||
|
loHTTP.SetRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
|
||||||
|
loHTTP.Send('state=' + lcState)
|
||||||
|
lnStatus = loHTTP.Status
|
||||||
|
lcResponse = loHTTP.ResponseText
|
||||||
|
CATCH TO loExHTTP
|
||||||
|
* eroare retea tranzitorie -> continuam polling pana la timeout
|
||||||
|
ENDTRY
|
||||||
|
|
||||||
|
IF lnStatus = 200
|
||||||
|
loJson = NULL
|
||||||
|
TRY
|
||||||
|
loJson = nfjsonread(lcResponse)
|
||||||
|
CATCH TO loExJson
|
||||||
|
This.Log('[' + lcStatePrefix + '] eroare parsare JSON: ' + loExJson.Message)
|
||||||
|
ENDTRY
|
||||||
|
IF TYPE('loJson') = 'O' AND !ISNULL(loJson)
|
||||||
|
IF TYPE('loJson.error') <> 'U'
|
||||||
|
lcExitCode = 'anaf_error'
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
IF TYPE('loJson.access_token') <> 'U' AND TYPE('loJson.refresh_token') <> 'U'
|
||||||
|
* Tokenuri primite - populare proprietati (fara valori de tokenuri in log)
|
||||||
|
This.cToken = loJson.access_token
|
||||||
|
This.cRefreshToken = loJson.refresh_token
|
||||||
|
This.dTokenGendate = DATE()
|
||||||
|
IF TYPE('loJson.expires_in') <> 'U'
|
||||||
|
This.dTokenExpdate = DATE() + INT(VAL(TRANSFORM(loJson.expires_in)) / 86400)
|
||||||
|
ELSE
|
||||||
|
This.dTokenExpdate = DATE() + 90
|
||||||
|
ENDIF
|
||||||
|
lcExitCode = 'success'
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
* {"status":"pending"} sau alt continut -> continuam polling
|
||||||
|
ENDIF
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
* asteptare 2s cu verificare Esc la fiecare 0.5s
|
||||||
|
lnStep = 0
|
||||||
|
DO WHILE lnStep < 4
|
||||||
|
lnKey = INKEY(0.5)
|
||||||
|
IF lnKey = 27 && Esc
|
||||||
|
lcExitCode = 'esc'
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
lnStep = lnStep + 1
|
||||||
|
ENDDO
|
||||||
|
IF lcExitCode = 'esc'
|
||||||
|
EXIT
|
||||||
|
ENDIF
|
||||||
|
ENDDO
|
||||||
|
WAIT CLEAR
|
||||||
|
This.Log('[' + lcStatePrefix + '] iesire: ' + lcExitCode)
|
||||||
|
|
||||||
|
DO CASE
|
||||||
|
CASE lcExitCode = 'success'
|
||||||
|
TRY
|
||||||
|
This.SaveToken()
|
||||||
|
AMESSAGEBOX('S-a generat token-ul eFactura, valabil pana la ' + DTOC(This.dTokenExpdate), 0 + 64, _Screen.Caption)
|
||||||
|
CATCH TO loExSave
|
||||||
|
* tokenul ramane in This.cToken; la reluarea operatiei va fi necesar PIN-ul din nou
|
||||||
|
AMESSAGEBOX('Tokenul a fost generat, dar salvarea in baza de date a esuat: ' + loExSave.Message + CHR(13) + ;
|
||||||
|
'Reluati operatia Token nou sau contactati suportul ROA.', 0 + 48, _Screen.Caption)
|
||||||
|
ENDTRY
|
||||||
|
|
||||||
|
CASE lcExitCode = 'esc'
|
||||||
|
AMESSAGEBOX('Ati anulat asteptarea. Daca ati introdus deja PIN-ul, autorizarea respectiva va fi ignorata; la reluare va trebui sa introduceti PIN-ul din nou.', 0 + 64, _Screen.Caption)
|
||||||
|
|
||||||
|
CASE lcExitCode = 'timeout'
|
||||||
|
AMESSAGEBOX('Nu s-a primit tokenul in 10 minute. Se deschide pagina pentru completare manuala; puteti si relua operatia Token nou.', 0 + 48, _Screen.Caption)
|
||||||
|
open_default_app(lcTokenURL)
|
||||||
|
|
||||||
|
CASE lcExitCode = 'anaf_error'
|
||||||
|
AMESSAGEBOX('Eroare la autorizarea ANAF: ' + TRANSFORM(NVL(loJson.error, '')) + '. Reluati operatia sau folositi completarea manuala (se deschide pagina care afiseaza codurile).', 0 + 48, _Screen.Caption)
|
||||||
|
open_default_app(lcTokenURL)
|
||||||
|
ENDCASE
|
||||||
|
|
||||||
|
Endfunc && newToken
|
||||||
|
|
||||||
* Actualizeaza data expirarii tokenului ANAF eFactura
|
* Actualizeaza data expirarii tokenului ANAF eFactura
|
||||||
* Se apeleaza din formularul anaf_token.do_executa
|
* Se apeleaza din formularul anaf_token.do_executa
|
||||||
@@ -523,10 +702,11 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
|||||||
* tcMesaj (OUT)
|
* tcMesaj (OUT)
|
||||||
|
|
||||||
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
Local loHTTP As 'winHTTP.winHTTPrequest.5.1'
|
||||||
Local lcRefreshToken, lcResponse, lcURL, llSucces, loJson
|
Local lcRefreshToken, lcResponse, lcURL, llSucces, loJson, loEx as Exception
|
||||||
llSucces = .F.
|
llSucces = .T.
|
||||||
lcRefreshToken = Alltrim(This.cRefreshToken)
|
lcRefreshToken = Alltrim(This.cRefreshToken)
|
||||||
tcMesaj = ''
|
tcMesaj = ''
|
||||||
|
SET STEP ON
|
||||||
If Empty(m.lcRefreshToken)
|
If Empty(m.lcRefreshToken)
|
||||||
tcMesaj = 'Completati Refresh Token'
|
tcMesaj = 'Completati Refresh Token'
|
||||||
This.Log(m.tcMesaj)
|
This.Log(m.tcMesaj)
|
||||||
@@ -539,12 +719,21 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
|||||||
loHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
|
loHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
|
||||||
loHTTP.Send([refresh_token=] + m.lcRefreshToken)
|
loHTTP.Send([refresh_token=] + m.lcRefreshToken)
|
||||||
|
|
||||||
CATCH
|
CATCH TO loEx
|
||||||
loHTTP = Createobject('MSXML2.XMLHTTP.6.0')
|
llSucces = .F.
|
||||||
loHTTP.Open('POST', lcURL, .F.)
|
|
||||||
loHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
loHTTP.Send([refresh_token=] + m.lcRefreshToken)
|
|
||||||
ENDTRY
|
ENDTRY
|
||||||
|
|
||||||
|
IF !m.llSucces OR TYPE('loHTTP') <> 'O'
|
||||||
|
TRY
|
||||||
|
loHTTP = Createobject('MSXML2.XMLHTTP.6.0')
|
||||||
|
loHTTP.Open('POST', lcURL, .F.)
|
||||||
|
loHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
loHTTP.Send([refresh_token=] + m.lcRefreshToken)
|
||||||
|
CATCH TO loEx
|
||||||
|
llSucces = .F.
|
||||||
|
AMESSAGEBOX(loEx.Message,0,_screen.Caption)
|
||||||
|
ENDTRY
|
||||||
|
ENDIF
|
||||||
|
|
||||||
llSucces = (TYPE('loHTTP') = 'O')
|
llSucces = (TYPE('loHTTP') = 'O')
|
||||||
IF m.llSucces
|
IF m.llSucces
|
||||||
@@ -578,7 +767,7 @@ select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat
|
|||||||
Endif
|
Endif
|
||||||
ELSE
|
ELSE
|
||||||
tcMesaj = 'Nu s-a regenerat token-ul! Status = ' + Transform(loHTTP.Status) + CRLF + m.lcResponse
|
tcMesaj = 'Nu s-a regenerat token-ul! Status = ' + Transform(loHTTP.Status) + CRLF + m.lcResponse
|
||||||
This.Log(m.tcMesaj, 0 + 48, _Screen.Caption)
|
This.Log(m.tcMesaj)
|
||||||
Endif
|
Endif
|
||||||
Endif
|
Endif
|
||||||
|
|
||||||
@@ -2154,7 +2343,7 @@ end;
|
|||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
IF m.llSucces
|
IF m.llSucces
|
||||||
* Transformam raspunsul JSON <EFBFBD>ntr-un obiect FoxPro
|
* Transformam raspunsul JSON intr-un obiect FoxPro
|
||||||
TRY
|
TRY
|
||||||
loJson = nfjsonread(m.lcResponse)
|
loJson = nfjsonread(m.lcResponse)
|
||||||
CATCH TO loEx
|
CATCH TO loEx
|
||||||
@@ -2167,7 +2356,7 @@ end;
|
|||||||
|
|
||||||
* Verificam daca exista mesaje disponibile
|
* Verificam daca exista mesaje disponibile
|
||||||
IF TYPE("loJson.mesaje") <> "U"
|
IF TYPE("loJson.mesaje") <> "U"
|
||||||
* Daca avem mesaje, le salvam <EFBFBD>ntr-un array
|
* Daca avem mesaje, le salvam intr-un array
|
||||||
*!* laMesaje = loJson.mesaje
|
*!* laMesaje = loJson.mesaje
|
||||||
*!* lnMesajeCount = ALEN(laMesaje, 1)
|
*!* lnMesajeCount = ALEN(laMesaje, 1)
|
||||||
|
|
||||||
@@ -2697,7 +2886,10 @@ select id, id_efactura, nr, articol, descriere, detalii, cantitate, um, pret, pr
|
|||||||
If m.tlShow Or Empty(m.lcToken) Or m.ldTokenExpDate <= Date()
|
If m.tlShow Or Empty(m.lcToken) Or m.ldTokenExpDate <= Date()
|
||||||
loFrmToken = Createobject("anaf_token", This)
|
loFrmToken = Createobject("anaf_token", This)
|
||||||
loFrmToken.Show(1)
|
loFrmToken.Show(1)
|
||||||
If m.lcToken <> loServer.cToken
|
*!* 07.07.2026
|
||||||
|
*!* dupa fluxul automat (newToken) datele sunt deja setate corect din expires_in
|
||||||
|
*!* (dTokenGendate = azi); suprascrierea cu +90 ramane doar pentru completarea manuala
|
||||||
|
If m.lcToken <> loServer.cToken And loServer.dTokenGendate <> Date()
|
||||||
loServer.dTokenGendate = Date()
|
loServer.dTokenGendate = Date()
|
||||||
loServer.dTokenExpdate = Date() + 90
|
loServer.dTokenExpdate = Date() + 90
|
||||||
Endif
|
Endif
|
||||||
@@ -2719,15 +2911,23 @@ select id, id_efactura, nr, articol, descriere, detalii, cantitate, um, pret, pr
|
|||||||
Endproc && SaveToken
|
Endproc && SaveToken
|
||||||
|
|
||||||
|
|
||||||
|
*!* 07.07.2026
|
||||||
|
*!* newToken - deleaga la AnafeFacturaServer.newToken (implementare unica FR-7)
|
||||||
|
*!* pattern identic cu refreshToken: loServer = This.AnafeFacturaServer
|
||||||
|
|
||||||
* Intoarce tokenul de acces la ANAF (eFactura) daca este salvat sau obtine un nou token
|
* Intoarce tokenul de acces la ANAF (eFactura) daca este salvat sau obtine un nou token
|
||||||
* Se apeleaza din formularul anaf_token.do_executa
|
* Se apeleaza din formularul anaf_token.do_executa
|
||||||
Function newToken
|
Function newToken
|
||||||
AMESSAGEBOX('Introduceti in calculator tokenul USB cu semnatura electronica' + Chr(13) + Chr(10) + ;
|
LOCAL loServer
|
||||||
'Se va deschide pagina ANAF de generare token. Introduceti PIN-ul pentru semnatura electronica.' + Chr(13) + Chr(10) + ;
|
loServer = This.AnafeFacturaServer
|
||||||
'Copiati codurile "Token" si "Refresh Token" afisate si completati-le in ROA.', 0 + 64, _Screen.Caption)
|
* Asigura cTokenUrl populat din optiunile firmei (citit de GetToken din citeste_optiune)
|
||||||
|
loServer.GetToken()
|
||||||
lcURL = [https://romfast.ro/oauth2/]
|
loServer.newToken()
|
||||||
open_default_app(m.lcURL)
|
* Propagare proprietati actualizate catre ANAFeFactura (consistent cu getToken)
|
||||||
|
This.token = loServer.cToken
|
||||||
|
This.refresh_token = loServer.cRefreshToken
|
||||||
|
This.token_gendate = loServer.dTokenGendate
|
||||||
|
This.token_expdate = loServer.dTokenExpdate
|
||||||
Endfunc
|
Endfunc
|
||||||
|
|
||||||
* Actualizeaza data expirarii tokenului ANAF eFactura
|
* Actualizeaza data expirarii tokenului ANAF eFactura
|
||||||
|
|||||||
@@ -299,9 +299,12 @@ Define Class oExportConfig As wwConfig
|
|||||||
Endfunc && Report2File
|
Endfunc && Report2File
|
||||||
|
|
||||||
************************************** INCEPUT : open_default_app
|
************************************** INCEPUT : open_default_app
|
||||||
|
*!* 07.07.2026
|
||||||
|
*!* open_default_app - intoarce .T./.F. dupa rezultatul ShellExecute (>32 = succes)
|
||||||
|
*!* apelantii existenti care ignora rezultatul nu sunt afectati
|
||||||
Procedure OPEN_DEFAULT_APP
|
Procedure OPEN_DEFAULT_APP
|
||||||
Parameters tcNumeFisier
|
Parameters tcNumeFisier
|
||||||
Local lcActiune
|
Local lcActiune, lnResult
|
||||||
|
|
||||||
Declare Integer ShellExecute In shell32.Dll ;
|
Declare Integer ShellExecute In shell32.Dll ;
|
||||||
Integer hndWin, ;
|
Integer hndWin, ;
|
||||||
@@ -311,8 +314,9 @@ Define Class oExportConfig As wwConfig
|
|||||||
String cDir, ;
|
String cDir, ;
|
||||||
Integer nShowWin
|
Integer nShowWin
|
||||||
lcActiune = "open"
|
lcActiune = "open"
|
||||||
ShellExecute(0, lcActiune, tcNumeFisier, "", "", 1)
|
lnResult = ShellExecute(0, lcActiune, tcNumeFisier, "", "", 1)
|
||||||
|
|
||||||
|
Return (m.lnResult > 32)
|
||||||
Endproc && open_default_app
|
Endproc && open_default_app
|
||||||
************************************** SFARSIT : open_default_app
|
************************************** SFARSIT : open_default_app
|
||||||
************************************** INCEPUT : getExcelMask
|
************************************** INCEPUT : getExcelMask
|
||||||
|
|||||||
BIN
roacont.PJT
BIN
roacont.PJT
Binary file not shown.
BIN
roacont.PJX
BIN
roacont.PJX
Binary file not shown.
BIN
roacont.exe
BIN
roacont.exe
Binary file not shown.
Reference in New Issue
Block a user