Array affected after sending it to a function - vba

I send an arrey with the length of 26 twice to a function like this:
....
SaveXML strXmlItem, DFCCM, SCTM, Zieltabelle
SaveXML strXmlItem, DFCCS, SCTS, Zieltabelle
....
After the first invokation:
SaveXML strXmlItem, DFCCM, SCTM, Zieltabelle
Content of strXmlItem are changed. This array with other variablesis definedlike this:
Dim strSql, strXmlItem(), strA2l, strHex As String
and the function is:
Private Function SaveXML(strarr(), DFCC As String, SCT As String, ByVal Zieltabelle As String)
strarr(4) = DFCC
strarr(6) = SCT
For K = 0 To UBound(strarr)
MsgBox strarr(K)
Next K
'XML-Syntax anpassen
For J = 1 To conAnzahlFelder - 1
strarr(J) = MakeQuotes(strarr(J)) & ", "
Next J
strarr(conAnzahlFelder) = MakeQuotes(strarr(conAnzahlFelder)) & ")"
' Anfügeabfrage zusammenbasteln
strSql = "Insert Into " & Zieltabelle & " ("
For J = 1 To conAnzahlFelder
strSql = strSql & "f" & Trim(CStr(J - 1)) & ", "
Next J
strSql = strSql & "f" & Trim(CStr(conAnzahlFelder)) & ") "
strSql = strSql & "Values ("
For J = 1 To conAnzahlFelder + 1
strSql = strSql & strarr(J - 1)
Next J
MsgBox strSql
DoCmd.RunSQL strSql
End Function
How can I solve the problem?

there are a lot of issues in your code. But to answer your question
first:
try:
Private Function SaveXML(ByVal strarr(), DFCC As String, SCT As String, ByVal Zieltabelle As String)
instead of
Private Function SaveXML(strarr(), DFCC As String, SCT As String, ByVal Zieltabelle As String)
Google for the difference between ByVal and ByRef.
Second:
you really should use Option Explicit on the beginning of each module. You use a lot of undeclared variables. This can cause additional issues.
Third:
Dim strSql, strXmlItem(), strA2l, strHex As String
generates only ONE string variable (strHex). The others are declared as Variant if you use that Syntax. This works in some other languages but not in VBA!
and last but not least:
you declare a Function but you do not return any value for it. Either you do not want to return something (then you shouldn't declare it as Function) or you should provide a return value.

Related

Finding the position of a specified string in another string

I need to find the position of a changing specified word in a string, and I need it to be very specific so it doesn't include words without spaces so say if I was looking for the word 'Hi' It would only return true if it was checking 'Hi' and not 'HiExample'.
Code:
Dim userString As String = userInput.Text
userString = userString.ToLower()
Dim d As New Dictionary(Of String, Integer)
Dim wordString = userString.ToLower().Split(" "c)
Dim iList As New List(Of String)()
For Each word In wordString
If d.ContainsKey(word) Then
d(word) += 1
iList.Add(word)
Else
d.Add(word, 1)
End If
Next
For Each de In d
For i As Integer = 0 To wordString.Count - 1
Dim index As Integer = userString.IndexOf(de.Key)
output.Text &= "Word: " & de.Key & " Occurrence: " & de.Value & " Position: " & GET POSTION OF EACH WORD HERE & Environment.NewLine
Next
Next
Checking for upper case or lower case will not be necessary as I have already converted the string into lower case.
Thanks,
Matt
you can try Regex
For Each de In d
Dim index As Integer = Regex.Matches(userString, "(?<=^|\b|\s)" & Regex.Escape(de.Key) & "(?=\s|\b|$)")(0).Index
Console.WriteLine("Word: " & de.Key & " Occurrence: " & de.Value & " Position: " & index)
Next
this might get you started

Cannot get SQL Query to work with SafeSqlLiteral function

I have a function SafeSqlLiteral, found online. It's a function to prevent SQL injection attacks. I want to use this function inside my SQL query like so:
Dim com As String = "SELECT * FROM Person WHERE " &
SafeSqlLiteral(SearchCriteria, 2)
SearchCriteria being user input. I want the user to be able to enter: strState LIKE 'M%' and show all the records matching a state like Maine. It feels like this would work. (SELECT * FROM Person WHERE strState LIKE 'M%')
I'm getting a whole bunch of errors (probably too many to post on here, but will post them if needed), and I'm having a hard time figuring out how to make my query work with the SafeSqlLiteral function.
Here is the SafeSqlLiteral function:
Public Function SafeSqlLiteral(theValue As System.Object,
theLevel As System.Object) As String
Dim strValue As String = DirectCast(theValue, String)
Dim intLevel As Integer = CInt(theLevel)
If strValue IsNot Nothing Then
If intLevel > 0 Then
strValue = strValue.Replace("'", "''")
strValue = strValue.Replace("--", "")
strValue = strValue.Replace("[", "[[]")
strValue = strValue.Replace("%", "[%]")
End If
If intLevel > 1 Then
Dim myArray As String() = New String() {"xp_ ", "update ", "insert ", "select ", "drop ", "alter ",
"create ", "rename ", "delete ", "replace "}
Dim i As Integer = 0
Dim i2 As Integer = 0
Dim intLenghtLeft As Integer = 0
For i = 0 To myArray.Length - 1
Dim strWord As String = myArray(i)
Dim rx As New Regex(strWord, RegexOptions.Compiled Or RegexOptions.IgnoreCase)
Dim matches As MatchCollection = rx.Matches(strValue)
i2 = 0
For Each match As Match In matches
Dim groups As GroupCollection = match.Groups
intLenghtLeft = groups(0).Index + myArray(i).Length + i2
strValue = strValue.Substring(0, intLenghtLeft - 1) + " " + strValue.Substring(strValue.Length - (strValue.Length - intLenghtLeft), strValue.Length - intLenghtLeft)
i2 += 5
Next
Next
End If
Return strValue
Else
Return strValue
End If
End Function
Thanks in advance for anyone helping me solve this problem! It's greatly appreciated!

Update multi table access db using vb.net

Can someone please help me with that?
My prob is that When i use dataAdapter.Update in this next construction i get a return value of zero (no line was updated but no reason or errors return).
The update sentense works when i run it using Access and other update requests works fine when i work on a single table.
Im Using:
vb.net \ visual studio 2012 \ access 2010 DB
I update the Data on my DataGridView and call the update function:
update command:
Private Function createGeneralUpdateStatement() As String
Return "UPDATE EntitysDataTbl INNER JOIN ManagersExtraDataTbl ON EntitysDataTbl.entityID = ManagersExtraDataTbl.managerID " + _
"SET EntitysDataTbl.entityUserName = [#EntitysDataTbl].entityUserName, " + _
"EntitysDataTbl.entityLastEntry = [#EntitysDataTbl].entityLastEntry, " + _
"ManagersExtraDataTbl.mPassword = [#ManagersExtraDataTbl].mPassword, " + _
"ManagersExtraDataTbl.workGroup = [#ManagersExtraDataTbl].workGroup, " + _
"ManagersExtraDataTbl.entityAccessType = [#ManagersExtraDataTbl].entityAccessType, " + _
"ManagersExtraDataTbl.mActive = [#ManagersExtraDataTbl].mActive" + _
"WHERE EntitysDataTbl.entityID= [#EntitysDataTbl].entityID"
End Function
The parameters are:
Dim parmList(2) As String
parmList(0) = "mPassword"
parmList(1) = "entityUserName"
and the update function is:
Public Function updateDB(ByVal updateCommand As String, ByVal parmList() As String, Optional ByVal insertCommand As String = "") As Boolean
Dim res As Boolean = False
SyncLock Me
Try
mainDataSet.EndInit()
mUpdateCommand = New OleDb.OleDbCommand(updateCommand, MyBase.getConnector)
For Each Str As String In parmList
If Not Str Is Nothing Then
If (Str.StartsWith("%")) Then
mUpdateCommand.Parameters.Add("#" & Str.Trim("%"), OleDb.OleDbType.Boolean, MAX_COL_LEN, Str.Trim("%"))
Else
mUpdateCommand.Parameters.Add("[#" & Str & "]", OleDb.OleDbType.VarChar, MAX_COL_LEN, Str)
End If
End If
Next
mDataAdapter.UpdateCommand = mUpdateCommand
If (Not insertCommand.Equals("")) Then
mInsertCommand = New OleDb.OleDbCommand(insertCommand, MyBase.getConnector)
For Each Str As String In parmList
If Not Str Is Nothing Then
'If Str.Equals("RuleIDNum") Then
' Continue For
'End If
If (Str.StartsWith("%")) Then
mInsertCommand.Parameters.Add("#" & Str.Trim("%"), OleDb.OleDbType.Boolean, MAX_COL_LEN, Str.Trim("%"))
Else
mInsertCommand.Parameters.Add("[#" & Str & "]", OleDb.OleDbType.VarChar, MAX_COL_LEN, Str)
End If
End If
Next
mDataAdapter.InsertCommand = mInsertCommand
End If
Dim i As Integer = mDataAdapter.Update(mainDataSet)
'ERROR - i = 0 => NO LINE WAS UPDATED!!!!
res = True
Catch ex As Exception
res = False
End Try
mDBWasUpdated = res
End SyncLock
Return res
End Function

Not saving .txt file in vb.net

Cutting to the chase:
Function Create(ByVal network, ByVal location, ByVal type, ByVal requirement1, ByVal requirement2, ByVal requirement3, ByVal name)
Dim net As String = network
Dim loc As String = location
Dim typ As String = type
Dim nam As String = name
Dim req1 As String = requirement1
Dim req2 As String = requirement2
Dim req3 As String = requirement3
Dim Mission As New System.IO.StreamWriter("C:\" & nam & ".txt")
Mission.WriteLine("Name: " & net)
Mission.WriteLine("Network: " & net)
Mission.WriteLine("Location: " & loc)
Mission.WriteLine("Type: " & typ)
Mission.WriteLine("Requirement: " & req1)
Mission.WriteLine("Requirement: " & req2)
Mission.WriteLine("Requirement: " & req3)
Mission.Close()
Console.WriteLine("Written")
System.Threading.Thread.Sleep(3000)
End Function
No errors appear, but neither does the file in the filepath. I have it all declared when I call the function, so I know that its not the problem.
Help? :)
Sub Create(ByVal network As String, ByVal location As String,
ByVal type As String, ByVal requirement1 As String,
ByVal requirement2 As String, ByVal requirement3 As String,
ByVal name As String)
Dim net As String = network
Dim loc As String = location
Dim typ As String = type
Dim nam As String = name
Dim req1 As String = requirement1
Dim req2 As String = requirement2
Dim req3 As String = requirement3
If Not nam.EndsWith(".txt") Then
nam &= ".txt"
End If
Dim Mission As New System.IO.StreamWriter(Path.Combine(
System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Desktop), nam))
Mission.WriteLine("Name: " & net)
Mission.WriteLine("Network: " & net)
Mission.WriteLine("Location: " & loc)
Mission.WriteLine("Type: " & typ)
Mission.WriteLine("Requirement: " & req1)
Mission.WriteLine("Requirement: " & req2)
Mission.WriteLine("Requirement: " & req3)
Mission.Close()
Console.WriteLine("Written")
'System.Threading.Thread.Sleep(3000)
End Sub
first of all pal, you were passing the parameters as objects!!, second you dont have permission to save to c root directory unless you have administrator privilege, third the threading part at the end is completely useless, its blocking the UI and don't add up to any benefit.
at last but not least.
good luck

How can I generate GUIDs in Excel?

I have an excel file with one order on each row, and I want each order to have a unique identifier, so there will be a Unique ID column. Every time I fill a row, I want Excel to automatically populate the Unique ID column for me. I did some research and was pointed in the direction of GUIDs. I found the following code:
Function GenGuid() As String
Dim TypeLib As Object
Dim Guid As String
Set TypeLib = CreateObject("Scriptlet.TypeLib")
Guid = TypeLib.Guid
' format is {24DD18D4-C902-497F-A64B-28B2FA741661}
Guid = Replace(Guid, "{", "")
Guid = Replace(Guid, "}", "")
Guid = Replace(Guid, "-", "")
GenGuid = Guid
End Function
but I am not sure how I can implement it. Any help would be greatly appreciated. Thank you in advance.
The following Excel expression evaluates to a V4 GUID:
=CONCATENATE(DEC2HEX(RANDBETWEEN(0,4294967295),8),"-",DEC2HEX(RANDBETWEEN(0,65535),4),"-",DEC2HEX(RANDBETWEEN(16384,20479),4),"-",DEC2HEX(RANDBETWEEN(32768,49151),4),"-",DEC2HEX(RANDBETWEEN(0,65535),4),DEC2HEX(RANDBETWEEN(0,4294967295),8))
-or (depending on locale setting/decimal and list separators)-
=CONCATENATE(DEC2HEX(RANDBETWEEN(0;4294967295);8);"-";DEC2HEX(RANDBETWEEN(0;65535);4);"-";DEC2HEX(RANDBETWEEN(16384;20479);4);"-";DEC2HEX(RANDBETWEEN(32768;49151);4);"-";DEC2HEX(RANDBETWEEN(0;65535);4);DEC2HEX(RANDBETWEEN(0;4294967295);8))
Note that the first character of the third group is always 4 to signify a V4 (pseudo-random number generated) GUID/UUID per RFC 4122 section 4.4.
Also note that the first character of the fourth group is always between 8 and B per the same RFC.
Standard disclaimer: the resulting GUIDs/UUIDs are not cryptographically strong.
Edit: remove invisible characters
I used the following function in v.2013 excel vba to create a GUID and is working well..
Public Function GetGUID() As String
GetGUID = Mid$(CreateObject("Scriptlet.TypeLib").GUID, 2, 36)
End Function
I know this question is answered, but I think the code in question should look something like what's on this page: http://snipplr.com/view/37940/
Haven't tested, but this code seems to tap into the Windows API to get its GUID's - I would try putting that in a public module and typing =GetGUId() in an Excel cell to see what I'd get. If it works in VB6 you have a great deal of a good chance it works in VBA as well:
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Declare Function CoCreateGuid Lib "OLE32.DLL" (pGuid As GUID) As Long
Public Function GetGUID() As String
'(c) 2000 Gus Molina
Dim udtGUID As GUID
If (CoCreateGuid(udtGUID) = 0) Then
GetGUID = _
String(8 - Len(Hex$(udtGUID.Data1)), "0") & Hex$(udtGUID.Data1) & _
String(4 - Len(Hex$(udtGUID.Data2)), "0") & Hex$(udtGUID.Data2) & _
String(4 - Len(Hex$(udtGUID.Data3)), "0") & Hex$(udtGUID.Data3) & _
IIf((udtGUID.Data4(0) < &H10), "0", "") & Hex$(udtGUID.Data4(0)) & _
IIf((udtGUID.Data4(1) < &H10), "0", "") & Hex$(udtGUID.Data4(1)) & _
IIf((udtGUID.Data4(2) < &H10), "0", "") & Hex$(udtGUID.Data4(2)) & _
IIf((udtGUID.Data4(3) < &H10), "0", "") & Hex$(udtGUID.Data4(3)) & _
IIf((udtGUID.Data4(4) < &H10), "0", "") & Hex$(udtGUID.Data4(4)) & _
IIf((udtGUID.Data4(5) < &H10), "0", "") & Hex$(udtGUID.Data4(5)) & _
IIf((udtGUID.Data4(6) < &H10), "0", "") & Hex$(udtGUID.Data4(6)) & _
IIf((udtGUID.Data4(7) < &H10), "0", "") & Hex$(udtGUID.Data4(7))
End If
End Function
Thanks Gus Molina!
If this code works (which I don't doubt), I think you'd get a new set of GUID's whenever the function gets evaluated, which means everytime the sheet gets calculated - when you're saving the workbook, for example. Make sure to copy-pastespecial-values if you need the GUID's for later use... which is somewhat likely.
A VBA approach based on generating random numbers using the Rnd() function, and not on external API calls or Scriptlet.TypeLib:
Public Function CreateGUID() As String
Do While Len(CreateGUID) < 32
If Len(CreateGUID) = 16 Then
'17th character holds version information
CreateGUID = CreateGUID & Hex$(8 + CInt(Rnd * 3))
End If
CreateGUID = CreateGUID & Hex$(CInt(Rnd * 15))
Loop
CreateGUID = "{" & Mid(CreateGUID, 1, 8) & "-" & Mid(CreateGUID, 9, 4) & "-" & Mid(CreateGUID, 13, 4) & "-" & Mid(CreateGUID, 17, 4) & "-" & Mid(CreateGUID, 21, 12) & "}"
End Function
This essentially is a VBA implementation of NekojiruSou's answer (it also generates a v4 GUID), and carries the same limitations, but will work in VBA and might be easier to implement.
Note that you can omit the last line to not return the dashes and curly braces in the result.
I found pretty solution here:http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=751237&msg=8634441
Option Explicit
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Declare Function CoCreateGuid Lib "ole32" (pguid As GUID) As Long
Private Declare Function StringFromGUID2 Lib "ole32" ( _
rguid As GUID, ByVal lpsz As Long, ByVal cchMax As Long) As Long
Public Function CreateGUID() As String
Dim NewGUID As GUID
CoCreateGuid NewGUID
CreateGUID = Space$(38)
StringFromGUID2 NewGUID, StrPtr(CreateGUID), 39
End Function
This is based on a javascript implementation.
Private Function getGUID() As String
Call Randomize 'Ensure random GUID generated
getGUID = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
getGUID = Replace(getGUID, "y", Hex(Rnd() And &H3 Or &H8))
Dim i As Long: For i = 1 To 30
getGUID = Replace(getGUID, "x", Hex$(Int(Rnd() * 16)), 1, 1)
Next
End Function
Same same for german Excel version:
=VERKETTEN(DEZINHEX(ZUFALLSBEREICH(0;4294967295);8);"-";DEZINHEX(ZUFALLSBEREICH(0;65535);4);"-";DEZINHEX(ZUFALLSBEREICH(16384;20479);4);"-";DEZINHEX(ZUFALLSBEREICH(32768;49151);4);"-";DEZINHEX(ZUFALLSBEREICH(0;65535);4);DEZINHEX(ZUFALLSBEREICH(0;4294967295);8))
Since windows update taken out "Scriptlet.TypeLib", try the following:
Declare Function CoCreateGuid Lib "ole32" (ByRef GUID As Byte) As Long
Public Function GenerateGUID() As String
Dim ID(0 To 15) As Byte
Dim N As Long
Dim GUID As String
Dim Res As Long
Res = CoCreateGuid(ID(0))
For N = 0 To 15
GUID = GUID & IIf(ID(N) < 16, "0", "") & Hex$(ID(N))
If Len(GUID) = 8 Or Len(GUID) = 13 Or Len(GUID) = 18 Or Len(GUID) = 23 Then
GUID = GUID & "-"
End If
Next N
GenerateGUID = GUID
End Function
Alternatively,
if you are connecting to SQL Server 2008 or higher, try to use the SQL NEWID() function instead.
I created a VBA function that works both on mac and windows:
https://github.com/Martin-Carlsson/Business-Intelligence-Goodies/blob/master/Excel/GenerateGiud/GenerateGiud.bas
'Generates a guid, works on both mac and windows
Function Guid() As String
Guid = RandomHex(3) + "-" + _
RandomHex(2) + "-" + _
RandomHex(2) + "-" + _
RandomHex(2) + "-" + _
RandomHex(6)
End Function
'From: https://www.mrexcel.com/forum/excel-questions/301472-need-help-generate-hexadecimal-codes-randomly.html#post1479527
Private Function RandomHex(lngCharLength As Long)
Dim i As Long
Randomize
For i = 1 To lngCharLength
RandomHex = RandomHex & Right$("0" & Hex(Rnd() * 256), 2)
Next
End Function
I recently ran into problems using CreateObject("Scriptlet.TypeLib") in some vba code.
So based on NekojiruSou excel functions wrote the following which should work without any specific excel functions. This can be used to develop a user defined function in excel.
Public Function Get_NewGUID() As String
'Returns GUID as string 36 characters long
Randomize
Dim r1a As Long
Dim r1b As Long
Dim r2 As Long
Dim r3 As Long
Dim r4 As Long
Dim r5a As Long
Dim r5b As Long
Dim r5c As Long
'randomValue = CInt(Math.Floor((upperbound - lowerbound + 1) * Rnd())) + lowerbound
r1a = RandomBetween(0, 65535)
r1b = RandomBetween(0, 65535)
r2 = RandomBetween(0, 65535)
r3 = RandomBetween(16384, 20479)
r4 = RandomBetween(32768, 49151)
r5a = RandomBetween(0, 65535)
r5b = RandomBetween(0, 65535)
r5c = RandomBetween(0, 65535)
Get_NewGUID = (PadHex(r1a, 4) & PadHex(r1b, 4) & "-" & PadHex(r2, 4) & "-" & PadHex(r3, 4) & "-" & PadHex(r4, 4) & "-" & PadHex(r5a, 4) & PadHex(r5b, 4) & PadHex(r5c, 4))
End Function
Public Function Floor(ByVal X As Double, Optional ByVal Factor As Double = 1) As Double
'From: http://www.tek-tips.com/faqs.cfm?fid=5031
' X is the value you want to round
' Factor is the multiple to which you want to round
Floor = Int(X / Factor) * Factor
End Function
Public Function RandomBetween(ByVal StartRange As Long, ByVal EndRange As Long) As Long
'Based on https://msdn.microsoft.com/en-us/library/f7s023d2(v=vs.90).aspx
' randomValue = CInt(Math.Floor((upperbound - lowerbound + 1) * Rnd())) + lowerbound
RandomBetween = CLng(Floor((EndRange - StartRange + 1) * Rnd())) + StartRange
End Function
Public Function PadLeft(text As Variant, totalLength As Integer, padCharacter As String) As String
'Based on https://stackoverflow.com/questions/12060347/any-method-equivalent-to-padleft-padright
' with a little more checking of inputs
Dim s As String
Dim inputLength As Integer
s = CStr(text)
inputLength = Len(s)
If padCharacter = "" Then
padCharacter = " "
ElseIf Len(padCharacter) > 1 Then
padCharacter = Left(padCharacter, 1)
End If
If inputLength < totalLength Then
PadLeft = String(totalLength - inputLength, padCharacter) & s
Else
PadLeft = s
End If
End Function
Public Function PadHex(number As Long, length As Integer) As String
PadHex = PadLeft(Hex(number), 4, "0")
End Function
For generating random guids using just the Rnd() function, not using any libraries or APIs, the simplest I can think of is this:
' UUID Version 4 (random)
Function GetUUID4()
Dim guid As String
Dim i As Integer
Dim r As Integer
guid = ""
Randomize
For i = 0 To 31
' random digit 0..15
r = Rnd() * 15
' add dash separators
If (i = 8) Or (i = 12) Or (i = 16) Or (i = 20) Then guid = guid & "-"
' uuid4 version info in 12th and 16th digits
If (i = 12) Then r = 4
If (i = 16) Then r = (r And 3 Or 8)
' add as hex digit
guid = guid & Hex(r)
Next i
GetUUID4 = guid
End Function
If you are inserting records into a database you can use this way to make a GUID.
It is probably the most simplest and easiest way to implement as you don't need a complex VBA function as you use the built in SQL function.
The statement uses NewID(),
The syntax is as follows,
INSERT INTO table_name (ID,Column1,Column2,Column3)
VALUES (NewID(),value1,value2,value3)
In VBA syntax it is as follows,
strSql = "INSERT INTO table_name " _
& "(ID,Column1,Column2,Column3) " _
& "VALUES (NewID(),value1,value2,value3)"
And if you need to concatenate values, just treat it as a string and concatenate as you would normally for a SQL statement,
strSql = "INSERT INTO table_name " _
& "(ID,Column1,Column2,Column3) " _
& "VALUES (" & "NewID()" & "," & "value1" & "," & "value2" & "," & "value3" & ")"
Function funGetGuid() As String
Const URL As String = "http://www.guidgen.com/"
Const strMask As String = "value="
Dim l As Long
Dim txt As String
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
txt = .responseText
End With
Do
l = InStr(l + 1, txt, strMask)
If l = 0 Then Exit Do
funGetGuid = Mid$(txt, l + Len(strMask) + 1, 36)
Loop
End Function