VBA - Naming of variables from array - arrays

Good Morning.
Is possible naming of variables with composition of text and another variables ?
Only for an example (not functional):
Components = "AA,BB,CC"
Values = "101,102,103"
ComponentsArr = Split(Components)
ValuesArr = Split(Values)
For i = 1 To UBound(ComponentsArr)
Let "Var" & ComponentsArr(i) = ValuesArr(i)
Next i

You might be able to use a dictionary to accomplish your purpose. You add key/value pairs to the dictionary. Then you can use the key to get the value.
Set a reference to MS Scripting runtime ('Microsoft Scripting Runtime')
Components = "AA,BB,CC"
Values = "101,102,103"
ComponentsArr = Split(Components, ",")
ValuesArr = Split(Values, ",")
Dim dict As New Scripting.Dictionary
For i = LBound(ComponentsArr) To UBound(ComponentsArr)
Call dict.Add(ComponentsArr(i), ValuesArr(i))
Next i
If dict.Exists("AA") Then
Debug.Print dict.Item("AA") 'prints 101
End If
See also: https://stackoverflow.com/a/915333/2559297

It might be easier to do it like the following:
Components = Array("AA", "BB", "CC")
Values = Array("101", "102", "103")
Then you wouldn't need ComponentsArr and ValuesArr.
For i = LBound(Components) To UBound(Components)
dict.Add(Components(i), Values(i))
Next i

Related

Deserialize a JSON array (I know - not array) in VB.net using JSON.NET

I've been killing myself for days on this and I can't figure it out. I'm by no means a programmer and this is my first attempt at working with JSON.
I have a GUI that I'm writing in VB.NET which gathers information for a script. I am using JSON.NET. I have it capturing the data entered into the GUI and exporting it as a JSON file, but I now need the functionality of reading the JSON file and putting the data back into the GUI.
I'm reading the contents of the datafile like this:
Dim Json As String = File.ReadAllText(fileDlg.FileName)
Dim data As JObject = JObject.Parse(Json)
Then going through each element of the file pulling the data in like this:
AD_DomainNameTB.Text = data.SelectToken("ActiveDirectory.DomainName")
AD_FQDNTB.Text = data.SelectToken("ActiveDirectory.FQDN")
AD_DomainControllerTB.Text = data.SelectToken("ActiveDirectory.DomainController")
AD_SVCUsernameTB.Text = data.SelectToken("ActiveDirectory.SVCUsername")
AD_SVCPasswordTB.Text = data.SelectToken("ActiveDirectory.SVCPassword")
AD_BaseDNTB.Text = data.SelectToken("ActiveDirectory.BaseDN")
Now, I need to cycle through an array of Sites and Site details and enter those into a datagridview on the GUI. I know I can do a for next loop for each of the items, but I don't know how to identify the number of items in the array.
The JSON data looks like this:
{
"ActiveDirectory": {
"DomainName": "CORP",
"FQDN": "corp.company.local",
"DomainController": "DC01",
"SVCUsername": "SVC_AD",
"SVCPassword": "SuperPass1",
"BaseDN": "OU=Active,DC=CORP,DC=Ccompany,DC=Local",
"CreateOUs": true,
"CreateGPOs": true,
"Sites": [
{
"Site": "Prod",
"HSA": "True",
"HSD": "True",
"HVD": null
},
{
"Site": "Test",
"HSA": "True",
"HSD": null,
"HVD": "True"
}
]
}
}
I've looked at the documentation on the site pretty extensively, but I can't find what I'm looking for. I've tried reading it into a dataset, like https://www.newtonsoft.com/json/help/html/DeserializeDataSet.htm, and I've tried creating a Class like Deserialize json array in vb.net but this doesn't make sense to me. It's way over my head.
Any help would be greatly appreciated. Please understand, that like I said, this is extremely new to me, so I need full details (don't assume that I know anything....because I don't!!)
(Using Newtonsoft.Json.Linq)
The ActiveDirectory.Sites node is of type JArray, which has a Count property.
You could iterate over the sites like this:
Dim Sites As JArray = data.SelectToken("ActiveDirectory.Sites")
For I = 0 To Sites.Count - 1
Dim Site = Sites(I)
' use `Site` and `I` in this loop body
Next
But if you don't care about the indexes, you should use a For Each loop:
Dim Sites As JArray = data.SelectToken("ActiveDirectory.Sites")
For Each Site In Sites
' use `Site` in this loop body
Next
JObject also lets you access properties using the following property lookup syntax:
Dim ActiveDirectory = data("ActiveDirectory")
Dim Sites = ActiveDirectory("Sites")
Dim SiteCount = Sites.Count
So another way you could write it is:
For Each Site In data("ActiveDirectory")("Sites")
' use `Site` in this loop body
Next
Based on the recommendations, I've gotten the code to work as I needed.Posting the full block below:
Dim Json As String = File.ReadAllText(fileDlg.FileName)
Dim data As JObject = JObject.Parse(Json)
Dim site
Dim SiteName
Dim HSA
Dim HSD
Dim HVD
AD_DomainNameTB.Text = data.SelectToken("ActiveDirectory.DomainName")
AD_FQDNTB.Text = data.SelectToken("ActiveDirectory.FQDN")
AD_DomainControllerTB.Text = data.SelectToken("ActiveDirectory.DomainController")
AD_SVCUsernameTB.Text = data.SelectToken("ActiveDirectory.SVCUsername")
AD_SVCPasswordTB.Text = data.SelectToken("ActiveDirectory.SVBPassword")
AD_BaseDNTB.Text = data.SelectToken("ActiveDirectory.BaseDN")
AD_CreateOUsCB.Checked = data.SelectToken("ActiveDirectory.CreateOUs")
AD_CreateGPOCB.Checked = data.SelectToken("ActiveDirectory.CreateGPOs")
Dim Sites As JArray = data.SelectToken("ActiveDirectory.Sites")
For Each site In Sites
SiteName = site.item("Site").ToString()
HSA = site.item("HSA").ToString()
HSD = site.item("HSD").ToString()
HVD = site.item("HVD").ToString()
If HSA = "" Then
HSA = False
End If
If HSD = "" Then
HSD = False
End If
If HVD = "" Then
HVD = False
End If
AD_SitesDatagrid.Rows.Add({SiteName, HSA, HSD, HVD})
Next
Now, there might be a better, more efficient way of going through the data in the array, but this worked.

How to loop through document and find words from predefined array and replace each word with words from another array

I want to loop word document and find words from arrayOne.
for example
arrayOne = ["john", "jack", "dog"]
and each word that matches to replace with words from arrayTwo
arrayTwo = ["ana", "tanja", "cat"]
You have not supplied any code with issues so there is nothing to fix, however you have asked 'How to find words and replace them'
Below are the steps you will need to code to achieve this: -
Build your array
Dim AryFNR(1,2) As String
AryFNR(0,0) = "john"
AryFNR(1,0) = "ana"
AryFNR(0,1) = "jack"
AryFNR(1,1) = "tanja"
...
Connect to the document
Dim WdDoc As Document
Set WdDoc = ThisDocument
...
Set WdDoc = Nothing
Connect to the selection ensuring it is in the connected document
Dim WdSlct As Selection
WdDoc.Content.Select
Set WdSlct = Selection
WdSlct.SetRange 0, 0
....
Set WdSlct = Nothing
Connect to Find and Replace and clear previous settings
Dim WdFnd As Find
Set WdFnd = WdSlct.Find
WdFnd.ClearAllFuzzyOptions
WdFnd.ClearFormatting
...
Set WdFnd = Nothing
Process your array using WdFnd on each item
Dim LngCounter As Long
For LngCounter = 0 To Ubound(AryFNR,2)
With WdFnd
.Execute FindText:=AryFNR(0, LngCounter), ReplaceWith:=AryFNR(1, LngCounter)
End With
Next
Some points you'll want to watch out for: -
Footnotes and Endnotes are not processed unless the selection in the Footnote/Endnote.
There are extra values on the .Execute command that you will want to set, depending on how you code it .Found may be useful.
That is enough information for you to start your own code to achieve your goal, enjoy!

reference dictionary within array output to listbox

Title kind of states my problem.
I'm using an Api (For Vertical Response, an email list manager) which works fine. But for a particular method returns an Array where the information I need to reference is within a Dictionary inside that Array.
Array[list_id, list_name, list_type, member_data] <- member_data being the dictionary housing all my goodies.
Best I've managed to get is the listbox outputting "com.verticalresponse.api.NVPair[]" for each member.
Code
Protected Sub GetBounces()
Dim listID As Integer = 284662333
Dim isMember As Boolean = False
Dim newSession As New loginArgs()
newSession.username = username
' Your VerticalResponse username
newSession.password = password
newSession.session_duration_minutes = "120"
Dim VRUser As New VRAPI()
Try
sessionID = VRUser.login(newSession)
Dim GetMembers As New getListMembersArgs()
Try
GetMembers.session_id = sessionID
GetMembers.list_id = listID
GetMembers.max_records = 8
Try
Dim listmembers As Array = VRUser.getListMembers(GetMembers)
lstBounces.DataSource = listmembers
lstBounces.DataValueField = ("member_data").ToString()
lstBounces.DataBind()
Catch ex As Exception
lstBounces.Text = "One: " + ex.ToString()
End Try
Catch listex As Exception
lstBounces.Text = "Two: " + listex.ToString()
End Try
Catch ex As System.Exception
lstBounces.Text = "Three: " + ex.ToString()
End Try
End Sub
Edit
I have taken the suggestion of Keith Mifsud and added a breakpoint just before the Databind. It shows me that "listmembers" has eight indices (currently only testing by searching for 8 (total list will be close to 8000, of which about 1900 are needed.))
Each of those 8 indices contains the 4 columns I am looking at, so when I use listmembers(3) as the datasource I'm really only searching the fourth result, not the member_data column...
Is there a correct way to reference the column of results?
Something like:
lstbounces.DataSource = listmembers( ,3)
But instead of that, a correct one?
I think you should set the datasource as the dictionary not the array holding it
Try
Dim listmembers As Array = VRUser.getListMembers(GetMembers)
lstBounces.DataSource = listmembers(3)
'As the datasource is a dictionary, I don't think you have to set up the display and value fields
'lstBounces.DataValueField = ("member_data").ToString()
lstBounces.DataBind()
Catch ex As Exception
lstBounces.Text = "One: " + ex.ToString()
End Try
UPDATE
Based on what the collection type (dictionary within every element of an array) I would recommend you use the .net DataView with allows for expandable rows. There are some very good tutorials which can guide you to create your view

How can I stop an array from repeating in Visual Basic 2010?

I have randomized an array, so questions are shown in a different order every time that the quiz is played, but would prefer it if the questions weren't able to repeat.
Here is how my array is set up:
Function loadQuestions()
Questions(0).Question = "Which of these words are an adjective?"
Questions(0).option1 = "Dog"
Questions(0).option2 = "Beautiful"
Questions(0).option3 = "Steven"
Questions(0).option4 = "Bird"
Questions(0).Answer = "B"
Questions(1).Question = "What's the adjective in this sentence:" & vbCrLf & "'Kelly handled the breakable glasses very carefully'"
Questions(1).option1 = "Kelly"
Questions(1).option2 = "Handled"
Questions(1).option3 = "Carefully"
Questions(1).option4 = "Breakable"
Questions(1).Answer = "D"
...
This is the function that calls the questions when the quiz begins.
Function GetQuestion(ByVal intQuestion As Integer)
tmrOne.Start()
If questionNumber < 11 Then
lblQuestionNumber.Text = "Question" & " " & questionNumber
Dim questionChosen As Integer
questionChosen = random.Next(25)
lblQuestion.Text = Questions(questionChosen).Question
btnAnswerA.Text = Questions(questionChosen).option1
btnAnswerB.Text = Questions(questionChosen).option2
btnAnswerC.Text = Questions(questionChosen).option3
btnAnswerD.Text = Questions(questionChosen).option4
strAnswer = Questions(questionChosen).Answer
questionNumber = questionNumber + 1
btnAnswerA.BackColor = Color.White
btnAnswerB.BackColor = Color.White
btnAnswerC.BackColor = Color.White
btnAnswerD.BackColor = Color.White
btnAnswerA.Enabled = True
btnAnswerB.Enabled = True
btnAnswerC.Enabled = True
btnAnswerD.Enabled = True
Return intQuestion
Else
MsgBox("You have finished")
End
End If
End Function
I have tried to find something on the internet to help with this, but haven't been successful or understood it as I am new to this. I have found ArrayList.RemoveAt but not sure that is the correct syntax to use with my array?
So, how do I stop my array from repeating a question once it has already been asked? Do I put them into another array?
Any help is greatly appreciated!
As I understand from your question, you are using an ArrayList. In that case, yes, the RemoveAt option sounds as the best alternative. Bear in mind that pure arrays (e.g., Dim Questions() As String) are the most efficient type of Collection; the main advantage of Lists/ArrayLists is precisely how easy is adding/removing elements, so if you use an ArrayList, better maximising one of its defining features.
The additional advantage in your specific case is that every time you remove an item, its position is filled (and the total number of items decreased). Thus, you have just to update the maximum value of your random number generator to the current number of indices (not elements, because the first index is zero).
In summary, the following changes in your code will deliver what you want:
If(Questions.Count > 0) Then
questionChosen = random.Next(0, Questions.Count - 1)
End If
And once you are done with it:
If(questionChosen >= 0 And questionChosen <= Questions.Count - 1) Then
Questions.RemoveAt(questionChosen)
End If

VBA. Array for search or replace

Need to found any symbol of array.
For example:
replace(string,[a,b,c,e,f,g],"a1b2c3d4e567");
result = "1234567"
How do it ?
If your goal is to remove all non-numeric characters, the following will work:
' Added reference for Microsoft VBScript Regular Expressions 5.5
Const s As String = "a1b2c3d4e567"
Dim regex2 As New RegExp
Dim a As String
regex2.Global = True
regex2.Pattern = "[^0-9]"
Dim a As String = regex2.Replace(s, "")
MsgBox (a) ' Outputs 1234567
If you are looking for specific characters, change the pattern.
AFAIK you are going to have to do this by consecutive calls to replace
result = "a1b2c3d4e567"
result = replace(result,"a","")
result = replace(result,"b","")
result = replace(result,"c","")
etc

Resources