I wanted to write an array of integers to a file.
I have a version that writes bytes to a file. The byte version works perfectly fine.
However, the integer array version does not. It throws the error
"Write failure. Error 1784."
I don't see where I went wrong.
This is the byte version:
Public Function WriteBytes(Buffer() As Byte) As Long
If WriteFile(hFile, _
Buffer(LBound(Buffer)), _
UBound(Buffer) - LBound(Buffer) + 1, _
WriteBytes, _
0) Then
Else
RaiseError HBF_WRITE_FAILURE
End If
End Function
But this one throws an error:
Public Function WriteIntegers(Buffer() As Integer) As Long
Dim lLen&
lLen = (UBound(Buffer) - LBound(Buffer) + 1) * 4 '1 integer=4 bytes
Dim lWritten&
If WriteFile(hFile, _
Buffer(LBound(Buffer)), _
lLen, _
lWritten, _
0) Then
Else
RaiseError HBF_WRITE_FAILURE
End If
WriteIntegers = lWritten
End Function
I am not sure where my error in the integer version is.
Does anybody see it?
Thank you for the help!
lLen = (UBound(Buffer) - LBound(Buffer) + 1) * 4 '1 integer=4 bytes
should be
lLen = (UBound(Buffer) - LBound(Buffer) + 1) * 2
Related
I am having problem in deploying VB6 apps into 64 bit windows. When I run the EXE, It gives out error "type mismatch"
The code is below :
Private Sub writedate (loc as string)
Dim dout(0 To 15) As Byte
Dim strdate_day as string
Dim strdate_mon as string
:
:
dout(0) = strdate_day 'This is the problem in 64 bit
dout(1) = strdate_mon
End sub
Public Function **Hex_Dec2**(ByVal val As String, ByVal start As Byte) As Byte
Dim MSB As Byte
Dim LSB As Byte
Dim Fbyte As Byte
Fbyte = 0
MSB = 0
LSB = 0
MSB = StrHEX_Dec(Mid(val, start, 1))
LSB = StrHEX_Dec(Mid(val, start + 1, 1))
Fbyte = (MSB * 16) + LSB
Hex_Dec2 = Fbyte
Debug.Print "val : " & val & " Fbyte : " & Fbyte
End Function
If I run the EXE file on 32 bit machine, it works fine. Absolutely no error.
The code HEX_DEC2 is a special function that converts string into byte. I have to use this function otherwise the value written will be incorrect. When I do : dout(0) = HEX_DEC2(strdate_day), it does not give "type mismatch" error on 64bit. For technical reason, i don't want to run this function
Strangely, the laptop that I am using to develop the app is 64 bit as well and doesn't give out any error when i run it from both the source code and the EXE file.
How do i overcome this problem ?
Upon trying to run my code I get the error "compile error: variable not defined" and it highlights my Sub line. Here is the code for reference.
Sub RI_Processing()
Dim i As Single
Dim Output() As Single 'Define this dynamic array for the solver output
Process the DMSO data
For i = 1 To 45 Step 1
Workbooks("Calibration Range 1 Normalized Profiles.xlsx").Activate
RawData.Range("C10:C649") = Sheet1.Columns("i").Values
SolverOk SetCell:="$E$7", MaxMinVal:=2, ValueOf:=0, ByChange:="$B$2:$B$4", _
Engine:=1, EngineDesc:="GRG Nonlinear"
SolverSolve
Workbooks("Simulated Fresnel Function.xlsx").Activate
Output(i, 1) = Sheet1.Range("B4").Values
Next i
i = 0
' Process the NaCl Data
For i = 1 To 102 Step 1
Workbooks("Calibration Range 1 Normalized Profiles.xlsx").Activate
RawData.Range("C10:C649") = Sheet2.Columns("i").Values
SolverOk SetCell:="$E$7", MaxMinVal:=2, ValueOf:=0, ByChange:="$B$2:$B$4", _
Engine:=1, EngineDesc:="GRG Nonlinear"
SolverSolve
Workbooks("Simulated Fresnel Function.xlsx").Activate
Output(i, 2) = Sheet1.Range("B4").Values
Next i
i = 0
' Process the Sucrose data
For i = 1 To 72 Step 1
Workbooks("Calibration Range 1 Normalized Profiles.xlsx").Activate
RawData.Range("C10:C649") = Sheet3.Columns("i").Values 'Copies the data of all 'i' columns to raw data for solver
SolverOk SetCell:="$E$7", MaxMinVal:=2, ValueOf:=0, ByChange:="$B$2:$B$4", _
Engine:=1, EngineDesc:="GRG Nonlinear"
SolverSolve 'Run solver
Workbooks("Simulated Fresnel Function.xlsx").Activate
Output(i, 3) = Sheet1.Range("B4").Values 'Put solver output to the matrix 'output' in the appropriate columns
Next i
End Sub
I have a string that looks something like 'NS-BATHROOMS 04288'
I only want the numbers.
I hve searched for answers, but none so far even get pst the compiler.
How can I do this?
without regex you can do it with: (altough VB6/VBA Code really isn`t nice to look at)
Public Function ReturnNonAlpha(ByVal sString As String) As String
Dim i As Integer
For i = 1 To Len(sString)
If Mid(sString, i, 1) Like "[0-9]" Then
ReturnNonAlpha = ReturnNonAlpha + Mid(sString, i, 1)
End If
Next i
End Function
I'd personally use regex. You can match given regex patterns to achieve what you need. This function matches only digits.
For VB6 you'd do something like:
Dim myRegExp, ResultString
Set myRegExp = New RegExp
myRegExp.Global = True
myRegExp.Pattern = "[\d]"
Then you'd go against your String.
https://support.microsoft.com/en-us/kb/818802
You can use this function for extract numerical chr as string value:
Public Function Str_To_Int(MyString As Variant) As Long
Dim i As Integer
Dim X As Variant
If IsNull(MyString) Or MyString = "" Then
Str_To_Int = 0
Exit Function
End If
For i = 1 To Len(MyString)
If IsNumeric(Mid(MyString, i, 1)) = True Then
X = Nz(X, "") & Mid(MyString, i, 1)
End If
Next i
Str_To_Int = Nz(X, 0)
End Function
Working on converting a Visual Basic SHA-256 encryption routine to work in LotusScript.
Is going well except for the VB's AscB command.
Found: "Use the AscB function to return the first byte of a string containing byte data."
Not finding way to do same in LotusScript.
See the LS CByte command comes close: "CByte returns an expression that has been converted to Byte."
Don't see way to have it return just the first Byte of the expression.
Any suggestions?
Derek
AscB is only appropriate for strings in single-byte character encoding. All LotusScript string data is Unicode represented in UTF16 double-byte encoding.
The LotusScript Uni() function returns a Long containing the integer value of the Unicode character. Since the input is a double byte character, the value returned by Uni() ranges from 0 to 65535. If you want to get the values of each of the two bytes, code like this will do the trick:
Dim ws As New NotesUIWorkspace
Dim s1 As String
Dim u1 As Long
Dim u2 As Long
Dim lowbyte As Integer
Dim highbyte As Integer
Dim b1 As Byte
Dim b2 as Byte
s1 = "Ʃ"
u1 = Uni(s1)
lowbyte = u1 Mod 256
highbyte = (u1 - lowbyte) / 256
b1 = Cbyte(lowbyte)
b2 = Cbyte(highbyte)
Call ws.Prompt(prompt_ok,"test",s1 + " " + Cstr(Cint(b1)) + " " + Cstr(Cint(b2)))
Would Asc, LeftB and RightB do what you need?
In my testing...
Lenb("A") = 2
Leftb("A", 1) = "A"
Asc(Leftb("A", 1)) = 65
Leftb("A", 2) = "A"
Asc(Leftb("A", 2)) = 65
Asc(Rightb(Leftb("A", 2), 1)) = 0
I am trying to MD5 hash user-supplied data (a file) using The Crypto functions in AdvApi32. All is well and good unless the file is very large (hundreds of MB. or larger) in which case I eventually get an OutOfMemory exception.
I figured that the solution would be to make repeated calls to CryptHashData using the same HashObject and processing only (for example) 4096 bytes at a time.
This appears to work, but the returned hash is incorrect.
Function HashFile(File As FolderItem) As String
Declare Function CryptAcquireContextW Lib "AdvApi32" (ByRef provider as Integer, container as Integer, providerName as WString, _
providerType as Integer, flags as Integer) as Boolean
Declare Sub CryptDestroyHash Lib "AdvApi32" (hashHandle as Integer )
Declare Function CryptCreateHash Lib "AdvApi32" (provider as Integer, algorithm as Integer, key as Integer, flags as Integer, _
ByRef hashHandle as Integer) as Boolean
Declare Function CryptHashData Lib "AdvApi32" (hashHandle as Integer, data as Ptr, length as Integer, flags as Integer) as Boolean
Declare Function CryptGetHashParam Lib "AdvApi32" (hashHandle as Integer, type as Integer, value as Ptr, ByRef length as Integer, _
flags as Integer) as Boolean
Const HP_HASHVAL = &h0002
Const HP_HASHSIZE = &h0004
Const MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0"
Const PROV_RSA_FULL = 1
Const CRYPT_NEWKEYSET = &h00000008
Const CALG_MD5 = &h00008003
Dim provider As Integer
Dim hashHandle As Integer
If Not CryptAcquireContextW(provider, 0, MS_DEF_PROV, PROV_RSA_FULL, 0) Then
If Not CryptAcquireContextW(provider, 0, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) Then
Raise New RuntimeException
End If
End If
If Not CryptCreateHash(provider, CALG_MD5, 0, 0, hashHandle) Then
Raise New RuntimeException
End If
Dim dataPtr As New MemoryBlock(4096)
Dim bs As BinaryStream
bs = bs.Open(File)
dataPtr.StringValue(0, 4096) = bs.Read(4096)
Do
If CryptHashData(hashHandle, dataPtr, dataPtr.Size, 0) Then
dataPtr = New MemoryBlock(4096)
dataPtr.StringValue(0, 4095) = bs.Read(4096)
End If
Loop Until bs.EOF
Dim size as Integer = 4
Dim toss As New MemoryBlock(4)
If Not CryptGetHashParam(hashHandle, HP_HASHSIZE, toss, size, 0) Then
Raise New RuntimeException
End If
size = toss.UInt32Value(0)
Dim hashValue As New MemoryBlock(size)
If Not CryptGetHashParam(hashHandle, HP_HASHVAL, hashValue, size, 0) Then
Raise New RuntimeException
End If
CryptDestroyHash(hashHandle)
//Convert binary to hex
Dim hexvalue As Integer
Dim hexedInt As String
Dim src As String = hashValue.StringValue(0, hashValue.Size)
For i As Integer = 1 To LenB(src)
hexvalue = AscB(MidB(src, i, 1))
hexedInt = hexedInt + RightB("00" + Hex(hexvalue), 2)
next
Return LeftB(hexedInt, LenB(hexedInt))
End Function
What am I doing wrong here? The output I get is consistent, but wrong.
Did you check that msdn example on C++ ?
Very similar answer to your question.
I think the problem is that since you read the data in blocks of 4096 bytes - when the data is not a multiple of 4096 you endup including unwanted trailing 0's or possibly garbage values. Try bs.Read(1) instead of bs.Read(4096) in the loop: Loop Until bs.EOF in-order to test if correct hash is being calculated now. If successful adjust your loop to tackle the remainder (%4096) bytes separately.