Pour une bonne gestion le type flottant double précision est insuffisant
car on ne gère pas avec des règles d’arrondi parfaitement définies dans tout le processus soit d’une comptabilité soit d’une gestion rigoureuse.
Après quelques recherches sur DCB (décimal codé binaire) ou BCD (binaire codé décimal) je me suis rabattu sur la dll oleaut32.dll de microsoft.
Cette DLL est présente sur tous les systèmes windows soit en 32 bits soit en 64 bits.
Elle compte 398 routines sous XP qui permettent de travailler avec les ‘variants’ compatibles de VB.
Je me suis intéressé plus particulièrement au variant DECIMAL.
Structure DECIMAL.
Représente un type de données décimal qui fournit un signe et l'échelle d'un certain nombre (aussi en coordonnées.)
Des variables décimales sont stockées sous forme de 96 bits (12 octets) entiers non signés à l'échelle par une puissance variable de 10.
La puissance de 10 facteurs de mise à l'échelle spécifie le nombre de chiffres à droite de la virgule décimale, et varie de 0 à 28.
( voir la structure dans le PRG)
Pour obtenir les prototypes et procédures générés automatiquement avec le prg PureDLLHelper,
Copyright ©2012 de Thomas <ts-soft> Schulz http://www.realsource.de/downloads/doc_ ... edllhelper
Après téléchargement vous pouvez utiliser soit le PRG 32bits soit le PRG 64bits
Oleaut32.DLL est à base de chaines de caractères en binaire string (BSTR) qui est une sorte d’Unicode avec la longueur définie avant la chaine
Pour éviter de noyer le lecteur sous le nombre de routines je n’ai utilisé que les routines potentiellement utiles pour les calculs en DECIMAL
Voici à titre d’exemple les quatre opérations et une mise en forme des nombres de sortie
(virgule ou point) (Signe – ou parenthèses) (Blocs groupés par millier ou pas)
Pour montrer la précision obtenue j’ai comparé une division en DECIMAL avec une division en nombre flottant double précision.
Voici les macros utilisées dans le PRG
Code : Tout sélectionner
Macro _q_t_ ; cette macro génère chr(34)
"
EndMacro
Macro _n (__n) ; cette macro associée à la précédente liste le nom de variable et son contenu en décimal
_q_t_#__n#=_q_t_+Str(__n)+" " ;
EndMacro
Macro _B (__B,_pr="%") ; macro associée à la première liste le nom de variable et son contenu en binaire
_q_t_#__B#=_q_t_+_pr+Bin(__B)+" "
EndMacro
Macro _f (__F,__nv=8) ; cette macro liste le nom de la variable et son contenu en simple précision
_q_t_#__F#=_q_t_+StrF(__f,__nv)+" "
EndMacro
Macro _d (__D,__nv=8) ; ; macro associée à la première liste le nom de variable et son contenu en double précision
_q_t_#__D#=_q_t_+StrD(__D,__nv)+" "
EndMacro
Macro _H (__H,__nv=#PB_Quad,_pr="$"); cette macro liste le nom de la variable et son contenu en Hexa
_q_t_#__H#=_q_t_+_pr+RSet(Hex(__H,__nv),__nv*4,"0")+" "
EndMacro
Macro _s (__S) ; cette macro liste le nom de la variable et son contenu en alpha
_q_t_#__S#=_q_t_+__S+" "
EndMacro
Macro _U (__U); cette macro liste le nom de la variable et son contenu en Unicode
_q_t_#__U#=_q_t_+StrU(__U)+" "
EndMacro
Macro _NL; cette macro donne le N° de ligne là où elle est appelée. elle peut servir de trace ou de repère ou même de N° d’erreur
"N°L=" + Str(#PB_Compiler_Line) + " ** "
EndMacro
Macro __nbc(__cc); cette macro recherché le nb de cycles machine pour optimiser le code
__cc.q
!RDTSC
!PUSH edx
!PUSH eax
!POP dword[v_#__cc]
!POP dword[v_#__cc+4]
EndMacro
Macro S_wap (a__,b__); cette macro swap les adresses de 2 tableaux identiques à partir de PB520 l car swap sur tableaux est KO
EnableASM
!pushd [a_#a__] [a_#b__]
!popd [a_#a__] [a_#b__]
DisableASM
EndMacro
Macro _AN_BIS (x); cette macro définie si une année x est bissextile ou non
((Not((x%4)<>0)) & ((1-(Not((x%100)<>0)) ) | (Not(((x>>2)%100)<>0)) ) )
EndMacro
Macro _HL (__HL,_pr="$")
_q_t_#__HL#=_q_t_+_PR+RSet(Hex(PeekL(@__HL),#PB_Long),8,"0")+" "
EndMacro
Code : Tout sélectionner
Global lcid.l=$40C ; Français FR:FR $40C ou 1036 avec virgule ou US US=> 1033 ou $409 pour utilisation avec point
Structure decimal Align #PB_Structure_AlignC
wReserved.w
scale.b ; nombre après la virgule
sign.b ; O signe positif 1 signe négatif
hi32.l
lo64.q
EndStructure
Structure bs
lg.l
tr.s{255}
EndStructure
Procedure.s PeekBSTR(*BSTR)
lenBSTR=PeekL(*BSTR-4)/2
Dim Char.c(lenBSTR)
For i=0 To lenBSTR
Char(i)=PeekC(*BSTR+i*2)
Next i
ProcedureReturn PeekS(@Char(0))
EndProcedure
;==========================================================================
; Generated with PureDLLHelper, Copyright ©2012 by Thomas <ts-soft> Schulz
;==========================================================================
Prototype SysAllocStringByteLen(a,b)
Prototype SysAllocString(a)
Prototype SysReAllocString(a,b)
Prototype SysAllocStringLen(a,b)
Prototype SysReAllocStringLen()
Prototype SysFreeString(a)
Prototype SysStringLen(a)
Prototype VariantInit(a)
Prototype VariantClear(a)
Prototype VariantCopy(a,b)
Prototype VariantCopyInd(a,b)
Prototype VarBstrFromUI1(a,b,c,d)
Prototype VarBstrFromI2(a,b,c,d)
Prototype VarBstrFromI4(a,b,c,d)
Prototype VarBstrFromR4(a,b,c,d)
Prototype VarBstrFromR8(a,b,c,d,e)
Prototype VarBstrFromCy(a,b,c,d)
Prototype VarBstrFromDate(a,b,c,d,e)
Prototype VarBstrFromDisp(a,b,c,d)
Prototype VarBstrFromBool(a,b,c,d)
Prototype VarBstrCat(a,b,c)
Prototype VarBstrFromDec(a,b,c,d)
Prototype VarBstrCmp(a,b,c,d)
Prototype VarBstrFromI8(a,b,c,d,e)
Prototype VarBstrFromUI8(a,b,c,d,e)
Prototype VarDecSub(a,b,c)
Prototype VarDecAbs(a,b)
Prototype VarDecAdd(a,b,c)
Prototype VarDecDiv(a,b,c)
Prototype VarDecMul(a,b,c)
Prototype VarDecFix(a,b)
Prototype VarDecInt(a,b)
Prototype VarDecNeg(a,b)
Prototype VarDecFromUI1(a,b)
Prototype VarDecFromI2(a,b)
Prototype VarDecFromI4(a,b)
Prototype VarDecFromR4(a,b)
Prototype VarDecFromR8(a.d,b)
Prototype VarDecFromDate(a,b,c)
Prototype VarDecFromCy(a,b)
Prototype VarDecFromStr(a,b,c,d)
Prototype VarDecFromDisp(a,b,c)
Prototype VarDecFromBool(a,b)
Prototype VarDecRound(a,b,c)
Prototype VarDecCmp(a,b)
Prototype VarDecFromI1(a,b)
Prototype VarDecFromUI2(a,b)
Prototype VarDecFromUI4(a,b)
Prototype VarDecCmpR8(a,b,c)
Prototype VarI2FromDec(a,b)
Prototype VarI4FromDec(a,b)
Prototype VarR4FromDec(a,b)
Prototype VarR8FromDec(a,b)
Prototype VarDateFromDec(a,b)
Prototype VarCyFromDec(a,b)
Prototype VarBoolFromDec(a,b)
Prototype VarUI1FromDec(a,b)
Prototype VarI1FromDec(a,b)
Prototype VarUI2FromDec(a,b)
Prototype VarUI4FromDec(a,b)
Prototype VarI8FromDec(a,b)
Prototype VarDecFromI8(a,b,c)
Prototype VarDecFromUI8(a,b,c)
Prototype VarUI8FromDec(a,b)
Prototype VarBstrFromI1(a,b,c,d)
Prototype VarBstrFromUI2(a,b,c,d)
Prototype VarBstrFromUI4(a,b,c,d)
Prototype VectorFromBstr(a,b)
Prototype BstrFromVector(a,b)
Prototype BSTR_UserSize(a,b,c)
Prototype BSTR_UserMarshal(a,b,c)
Prototype BSTR_UserUnmarshal(a,b,c)
Prototype BSTR_UserFree(a,b)
Prototype VarFormatNumber(a,b,c,d,e,f,g)
;************************* fin prototype *************************
Global VarDecAdd.VarDecAdd
Global VarDecDiv.VarDecDiv
Global VarDecMul.VarDecMul
Global VarDecSub.VarDecSub
Global VarDecAbs.VarDecAbs
Global VarDecFix.VarDecFix
Global VarDecInt.VarDecInt
Global VarDecNeg.VarDecNeg
Global VarDecFromUI1.VarDecFromUI1
Global VarDecFromI2.VarDecFromI2
Global VarDecFromI4.VarDecFromI4
Global VarDecFromR4.VarDecFromR4
Global VarDecFromR8.VarDecFromR8
Global VarDecFromDate.VarDecFromDate
Global VarDecFromCy.VarDecFromCy
Global VarDecFromStr.VarDecFromStr
Global VarDecFromDisp.VarDecFromDisp
Global VarDecFromBool.VarDecFromBool
Global VarDecRound.VarDecRound
Global VarDecCmp.VarDecCmp
Global VarDecFromUI2.VarDecFromUI2
Global VarDecFromUI4.VarDecFromUI4
Global VarDecCmpR8.VarDecCmpR8
Global VarI2FromDec.VarI2FromDec
Global VarI4FromDec.VarI4FromDec
Global VarR4FromDec.VarR4FromDec
Global VarR8FromDec.VarR8FromDec
Global VarDateFromDec.VarDateFromDec
Global VarCyFromDec.VarCyFromDec
Global VarBstrFromDec.VarBstrFromDec
Global VarBoolFromDec.VarBoolFromDec
Global VarUI1FromDec.VarUI1FromDec
Global VarDecFromI1.VarDecFromI1
Global VarI1FromDec.VarI1FromDec
Global VarUI2FromDec.VarUI2FromDec
Global VarUI4FromDec.VarUI4FromDec
Global VarI8FromDec.VarI8FromDec
Global VarDecFromI8.VarDecFromI8
Global VarDecFromUI8.VarDecFromUI8
Global VarUI8FromDec.VarUI8FromDec
Global SysAllocString.SysAllocString
Global SysReAllocString.SysReAllocString
Global SysAllocStringLen.SysAllocStringLen
Global SysReAllocStringLen.SysReAllocStringLen
Global SysFreeString.SysFreeString
Global SysStringLen.SysStringLen
Global VariantInit.VariantInit
Global VariantClear.VariantClear
Global VariantCopy.VariantCopy
Global VariantCopyInd.VariantCopyInd
Global VarBstrFromUI1.VarBstrFromUI1
Global VarBstrFromI2.VarBstrFromI2
Global VarBstrFromI4.VarBstrFromI4
Global VarBstrFromR4.VarBstrFromR4
Global VarBstrFromR8.VarBstrFromR8
Global VarBstrFromCy.VarBstrFromCy
Global VarBstrFromDate.VarBstrFromDate
Global VarBstrFromDisp.VarBstrFromDisp
Global VarBstrFromBool.VarBstrFromBool
Global VarBstrFromI1.VarBstrFromI1
Global VarBstrFromUI2.VarBstrFromUI2
Global VarBstrFromUI4.VarBstrFromUI4
Global BSTR_UserSize.BSTR_UserSize
Global BSTR_UserMarshal.BSTR_UserMarshal
Global BSTR_UserUnmarshal.BSTR_UserUnmarshal
Global BSTR_UserFree.BSTR_UserFree
Global VarBstrCat.VarBstrCat
Global VarBstrCmp.VarBstrCmp
Global VarBstrFromI8.VarBstrFromI8
Global VarBstrFromUI8.VarBstrFromUI8
Global VectorFromBstr.VectorFromBstr
Global BstrFromVector.BstrFromVector
Global VarFormatNumber.VarFormatNumber
Global SysAllocStringByteLen.SysAllocStringByteLen
Procedure.i oleaut32_LoadDLL()
Protected hDLL.i
If ExamineEnvironmentVariables()
While NextEnvironmentVariable()
If Trim(LCase(EnvironmentVariableName()))="systemroot"
; Debug EnvironmentVariableValue()
chem_syst$=EnvironmentVariableValue()
EndIf
Wend
EndIf
hDLL=OpenLibrary(#PB_Any,chem_syst$+"\system32\oleaut32.dll") ; ************** à changer suivant votre répertoire system *******
If hDLL<>0
SysAllocString=GetFunction(hDLL,"SysAllocString")
SysReAllocString=GetFunction(hDLL,"SysReAllocString")
SysAllocStringLen=GetFunction(hDLL,"SysAllocStringLen")
SysReAllocStringLen=GetFunction(hDLL,"SysReAllocStringLen")
SysFreeString=GetFunction(hDLL,"SysFreeString")
SysStringLen=GetFunction(hDLL,"SysStringLen")
VarBstrFromUI1=GetFunction(hDLL,"VarBstrFromUI1")
VarBstrFromI2=GetFunction(hDLL,"VarBstrFromI2")
VarBstrFromI4=GetFunction(hDLL,"VarBstrFromI4")
VarBstrFromR4=GetFunction(hDLL,"VarBstrFromR4")
VarBstrFromR8=GetFunction(hDLL,"VarBstrFromR8")
VarBstrFromCy=GetFunction(hDLL,"VarBstrFromCy")
VarBstrFromDate=GetFunction(hDLL,"VarBstrFromDate")
VarBstrFromDisp=GetFunction(hDLL,"VarBstrFromDisp")
VarBstrFromBool=GetFunction(hDLL,"VarBstrFromBool")
SysAllocStringByteLen=GetFunction(hDLL,"SysAllocStringByteLen")
VarDecSub=GetFunction(hDLL,"VarDecSub")
VarDecAbs=GetFunction(hDLL,"VarDecAbs")
VarDecAdd=GetFunction(hDLL,"VarDecAdd")
VarDecDiv=GetFunction(hDLL,"VarDecDiv")
VarDecMul=GetFunction(hDLL,"VarDecMul")
VarDecFix=GetFunction(hDLL,"VarDecFix")
VarDecInt=GetFunction(hDLL,"VarDecInt")
VarDecNeg=GetFunction(hDLL,"VarDecNeg")
VarDecFromUI1=GetFunction(hDLL,"VarDecFromUI1")
VarDecFromI2=GetFunction(hDLL,"VarDecFromI2")
VarDecFromI4=GetFunction(hDLL,"VarDecFromI4")
VarDecFromR4=GetFunction(hDLL,"VarDecFromR4")
VarDecFromR8=GetFunction(hDLL,"VarDecFromR8")
VarDecFromDate=GetFunction(hDLL,"VarDecFromDate")
VarDecFromCy=GetFunction(hDLL,"VarDecFromCy")
VarDecFromStr=GetFunction(hDLL,"VarDecFromStr")
VarDecFromDisp=GetFunction(hDLL,"VarDecFromDisp")
VarDecFromBool=GetFunction(hDLL,"VarDecFromBool")
VarDecRound=GetFunction(hDLL,"VarDecRound")
VarDecCmp=GetFunction(hDLL,"VarDecCmp")
VarI2FromDec=GetFunction(hDLL,"VarI2FromDec")
VarI4FromDec=GetFunction(hDLL,"VarI4FromDec")
VarR4FromDec=GetFunction(hDLL,"VarR4FromDec")
VarR8FromDec=GetFunction(hDLL,"VarR8FromDec")
VarDateFromDec=GetFunction(hDLL,"VarDateFromDec")
VarCyFromDec=GetFunction(hDLL,"VarCyFromDec")
VarBstrFromDec=GetFunction(hDLL,"VarBstrFromDec")
VarBoolFromDec=GetFunction(hDLL,"VarBoolFromDec")
VarUI1FromDec=GetFunction(hDLL,"VarUI1FromDec")
VarDecFromI1=GetFunction(hDLL,"VarDecFromI1")
VarDecFromUI2=GetFunction(hDLL,"VarDecFromUI2")
VarDecFromUI4=GetFunction(hDLL,"VarDecFromUI4")
VarI1FromDec=GetFunction(hDLL,"VarI1FromDec")
VarUI2FromDec=GetFunction(hDLL,"VarUI2FromDec")
VarUI4FromDec=GetFunction(hDLL,"VarUI4FromDec")
VarDecCmpR8=GetFunction(hDLL,"VarDecCmpR8")
VarI8FromDec=GetFunction(hDLL,"VarI8FromDec")
VarDecFromI8=GetFunction(hDLL,"VarDecFromI8")
VarDecFromUI8=GetFunction(hDLL,"VarDecFromUI8")
VarUI8FromDec=GetFunction(hDLL,"VarUI8FromDec")
BSTR_UserSize=GetFunction(hDLL,"BSTR_UserSize")
BSTR_UserMarshal=GetFunction(hDLL,"BSTR_UserMarshal")
BSTR_UserUnmarshal=GetFunction(hDLL,"BSTR_UserUnmarshal")
BSTR_UserFree=GetFunction(hDLL,"BSTR_UserFree")
GetErrorInfo=GetFunction(hDLL,"GetErrorInfo")
SetErrorInfo=GetFunction(hDLL,"SetErrorInfo")
CreateErrorInfo=GetFunction(hDLL,"CreateErrorInfo")
VarBstrFromI1=GetFunction(hDLL,"VarBstrFromI1")
VarBstrFromUI2=GetFunction(hDLL,"VarBstrFromUI2")
VarBstrFromUI4=GetFunction(hDLL,"VarBstrFromUI4")
VarBstrCat=GetFunction(hDLL,"VarBstrCat")
VarBstrCmp=GetFunction(hDLL,"VarBstrCmp")
VarBstrFromI8=GetFunction(hDLL,"VarBstrFromI8")
VarBstrFromUI8=GetFunction(hDLL,"VarBstrFromUI8")
VectorFromBstr=GetFunction(hDLL,"VectorFromBstr")
BstrFromVector=GetFunction(hDLL,"BstrFromVector")
VarFormatNumber=GetFunction(hDLL,"VarFormatNumber")
ProcedureReturn hDLL
EndIf
ProcedureReturn #False
EndProcedure
Procedure AnsiTOBStr(string$) ; By Zapman Inspired by Fr34k
Protected Unicode$=Space(Len(String$)*2+2)
Protected bstr_string.l
PokeS(@Unicode$,String$,-1,#PB_Unicode)
bstr_string=SysAllocString_(@Unicode$)
ProcedureReturn bstr_string
EndProcedure
Procedure.s ReadBstr(*String) ; By Fr34k
Result$=""
If *String
length.l=WideCharToMultiByte_(#CP_ACP,0,*String,-1,0,0,0,0)
*Buffer=AllocateMemory(length)
If *Buffer
WideCharToMultiByte_(#CP_ACP,0,*String,-1,*Buffer,length,0,0)
Result$=PeekS(*Buffer)
FreeMemory(*Buffer)
EndIf
EndIf
ProcedureReturn Result$
EndProcedure
Procedure AnsitoDEC(cAnsi.s,dy)
Bstr0=AnsiTOBstr(cAnsi)
VarDecFromStr(Bstr0,lcid,#LOCALE_NOUSEROVERRIDE,dy)
EndProcedure
Procedure.s DECtoAnsi(dy)
Bstr0=AnsiTOBstr(Space(255))
VarBstrFromDec(dy,lcid,#LOCALE_NOUSEROVERRIDE,Bstr0)
ProcedureReturn ReadBstr(PeekL(bstr0))
EndProcedure
dll_ole.l=oleaut32_LoadDLL()
;
Debug dll_ole
Define.decimal x,y,z,Dx,Dy,Dz,Du,Dv,dnx,dny,dnz,rx,ry,rz,Da,DB,Dc,DD,De
Define.w DW
Define.l bstr,bstr2
Define.q cy,Cz
Define a.bs,B.bs,c.bs,d.bs,e.bs
lcid=$409 ; US US
Vdpis.s="-3,14159265358979323846264338327" ; cette valeur avec virgule prise sur calc est plus prècise que la constante #pi
VDpi1000.s="-314159,265358979323846264"
Gosub essaipi
lcid=$40C ; FR,FR
; Vdpis.s="-3.14159265358979323846264338327" ; cette valeur avec point prise sur calc est plus prècise que la constante #pi
; VDpi1000.s="-314159.265358979323846"
Gosub essaipi
; *************** comparaison entre Dec et float double *************
For J=1 To 5
Vdr.d=j
AnsitoDEC(Str(j),dy)
Debug "**********"+_n(j)
For i=1 To 30
vdd.d=j/i
vdr.d=vdd/i
AnsitoDEC(Str(i),dx)
vardecdiv(dy,dx,dz)
vardecdiv(dz,dx,dnz)
Debug _n(i)+" "+_d(vdd,18)+LSet(" DEC="+DECtoAnsi(dz), 33 ," ")+" "+_d(vdr,18)+LSet(" DEC="+DECtoAnsi(dnz),33," ")
Next
Next
End
;************************************************************************************************************************************
;************************* subroutine avec format (point ou virgule) (signe ou parenthèse) (bloc par millier ou pas) ****************
;************************************************************************************************************************************
;************* soit avec virgule lcid=$40C pour FR soit avec point à la place de la virgule avec lcid=$409 pour US **********************************************
essaipi:
If lcid=$40C
vdpis=ReplaceString(vdpis, ".", "," )
VDpi1000=ReplaceString(vdpi1000, ".", "," )
Else
vdpis=ReplaceString(vdpis, ",", "." )
vdpi1000=ReplaceString(vdpi1000, ",", "." )
EndIf
posv.l=FindString(vdpis, "," )
posp.l=FindString(vdpis, "." )
posv10.l=FindString(vdpi1000, "," )
posp10.l=FindString(vdpi1000, "." )
Debug _nl+_n(posv)+_n(posp)+_n(posv10)+_n(posp10)+_hl(lcid)
AnsitoDEC(vdpis,dnx)
Debug Space(12)+_s(vdpis)
Debug Space(15)+_d(#PI,18); #pi est toujours défini avec un point
Debug "decimal PI après= "+DECtoAnsi(dnx)
vardecmul(dnx,dnx,dny)
Debug "decimal PI*PI après= "+dectoansi(dny)
VarDecRound(dny,4,dnz)
Debug "decimal round4 PI*PI après= "+dectoansi(dnz)
vardecsub(dny,dnx,dy)
Debug "decimal PI*PI après= "+dectoansi(dy)
VarDecRound(dy,6,dnz)
Debug "decimal round 6 PI*PI-PI après= "+dectoansi(dnz)
vardecadd(dy,dnx,ry)
Debug "decimal PI*PI-PI+PI après= "+dectoansi(ry)
VarDecRound(ry,6,dnz)
Debug "decimal round 6 PI*PI-PI+PI après= "+dectoansi(dnz)
;******************************************* FORMAT essai ***********************************
; VarFormatNumber function This topic has Not yet been rated-Rate this topic
;
; Formats a variant containing numbers INTO a string form.
; Syntax C++ HRESULT VarFormatNumber(_In_ LPVARIANT pvarIn,_In_ INT iNumDig,_In_ INT iIncLead,_In_ INT iUseParens,_In_ INT iGroup,_In_ ULONG dwFlags,_Out_ BSTR*pbstrOut);
;
; Parameters
; pvarIn[IN] The variant containing the value To format.
; iNumDig[IN] The number of digits To pad To after the decimal point.Specify-1 To use the system Default value.
; iIncLead[IN] Specifies whether To include the leading digit on numbers.
; Value Meaning
; -2 Use the system Default.
; -1 Include the leading digit.
; 0 Do Not include the leading digit.
; iUseParens[IN] Specifies whether negative numbers should use parentheses.
; Value Meaning
; -2 Use the system Default.
; -1 Use parentheses.
; 0 Do Not use parentheses.
; iGroup[IN] Specifies whether thousands should be grouped. For example 10,000 versus 10000.
; Note Regular numbers And currencies have separate system defaults For all the above options.
; Value Meaning
; -2 Use the system Default.
; -1 Group thousands.
; 0 Do Not group thousands.
; dwFlags[IN] VAR_CALENDAR_HIJRI is the only flag that can be set.
; pbstrOut[OUT] Points To the formatted string that represents the variant.
;
; Return value
; This function can Return one of these values.
; Return code Description
; S_OK Success.
; E_INVALIDARG One Or more of the arguments is Not valid.
AnsitoDEC(vdpi1000,rx)
pi1000.s=dectoansi(rx)
Debug _s(pi1000)
bstr2=SysAllocString(@vdpi1000)
resul=VarFormatNumber(rx,-1,-2,-2,-2,0,bstr2)
; Debug _n(ry\hi32)+_n(ry\lo64)+_n(ry\sign)
Debug _n(resul)
Debug("decimal PI Format = "+ReadBstr(PeekL(bstr2)))+" toujours avec virgule car la fonction tient compte de la région"
Debug " options régionales et linguistiques dans le panneau de configuration"
resul=VarFormatNumber(rx,6,-2,-1,-2,0,bstr2)
Debug _n(resul)
Debug("decimal PI Format () = "+ReadBstr(PeekL(bstr2)))+" avec parenthèses pour les nombres négatifs"
Debug "*************** fin 1 ****************"
Return
Ils sont présentés dans la doc Microsoft utilisable en recherchant dans Google "Microsoft nom de la fonction"
Ps il existe une lib oleaut32.lib dans la librairie de PB mais celle-ci est incomplète c’est pourquoi j’ai utilisé la DLL présente sur tous les systèmes windows
A+