I have this structure in Visual Basic .net
Private Structure queueT
Public name As String
Public parent As String
Public limitat As Integer
Public maxlimit As Integer
And this is the data I get, which I have stored in a one dimensional String array (just pasting 3):
!re=.id=*10000B0=name=Up-PBX=parent=Up=packet-mark=pack_pbx=limit-at=256000=queue=PCQ_Up=priority=1=max-limit=512000=burst-limit=0=burst-threshold=0=burst-time=00:00:00=invalid=true=disabled=true=comment=PBX
!re=.id=*10000C7=name=Down_Mauro=parent=Down=packet-mark==limit-at=315000=priority=8=max-limit=5000000=burst-limit=0=burst-threshold=0=burst-time=00:00:00=invalid=false=disabled=true
!re=.id=*10000C8=name=Down_Mauro_dom=parent=Down_Mauro=packet-mark=pack_Mauro_dom=limit-at=40000=queue=PCQ_Down=priority=2=max-limit=400000=burst-limit=0=burst-threshold=0=burst-time=00:00:00=invalid=false=disabled=true
I need to store the information in my structure so it looks like this:
queueT.name = UP-PBX
queueT.parent = UP
queueT.limitat = 256000
queueT.maxlimit = 512000
I only need the information mentioned above, not the rest. How can I do that?
Thanks!!
It looks like it's a key/value pairing after the first value. From your sample something like this could work.
Private Function queueTParse(item As String) As queueT
Dim queueValues = item.Split("=")
Dim queueTItem = New queueT
For i As Integer = 1 To queueValues.Length - 1 Step 2
Select Case queueValues(i)
Case "name"
queueTItem.name = queueValues(i + 1)
Case "parent"
queueTItem.parent = queueValues(i + 1)
Case "limit-at"
queueTItem.limitat = queueValues(i + 1)
Case "max-limit"
queueTItem.maxlimit = queueValues(i + 1)
End Select
Next
Return queueTItem
End Function
Related
(revamped question)
I need to format an input data structure for an RPG web service. I've tried using a list and it does not work. When I try this code:
Dim clist As New List(Of LabelView.PASSBACK.dscustomers)
clist.Add(New LabelView.PASSBACK.dscustomers() With {.BALANCEDUE = 185.42, .CREATIONDATE = 20200101, .CUSTOMERID = 1, .CUSTOMERTYPE = "ACTIVE", .FIRSTNAME = "Pat", .LASTNAME = "Smith"})
clist.Add(New LabelView.PASSBACK.dscustomers() With {.BALANCEDUE = 185.42, .CREATIONDATE = 20200101, .CUSTOMERID = 2, .CUSTOMERTYPE = "ACTIVE", .FIRSTNAME = "Jordan", .LASTNAME = "Jones"})
input.DSCUSTOMERS = clist
// ^^ Intellisense error:
// Value of type 'List (Of dsCustomers)' cannot be converted to 'dscustomers()'.
I can't figure out how to programmatically build something compatible. When I try this:
Dim client As PASSBACK.PASSBACK = New PASSBACK.PASSBACK()
Dim input As PASSBACK.passbackInput = New PASSBACK.passbackInput
input.DSCUSTOMERS(0).FIRSTNAME = "Hello"
It compiles but when I run I get 'Object reference not set to an instance of an object.'
Your issue with this line:
input.DSCUSTOMERS = clist
Is because DCUSTOMERS is an array (the "dcustomers()" of your error message) and a List(Of dcustomer) can't be directly assigned to an array.
There is a conversion function on List(Of T) that will give you an array T() called ToArray. It requires only a small change to your code:
input.DSCUSTOMERS = clist.ToArray()
This will make a new array with the same contents as the List (if dcustomers is a Class then the contents of the array will be exactly the same objects, whereas if it's a Structure then they will be copies) and assign it to DCUSTOMERS.
If I have a string "cboEnoughMoney(0)", is it possible to retrieve the control from a control array that I have in my form, cboEnoughMoney?
In my code, I try to refer to the control in this way:
frm.Controls(sControlName).ListIndex = -1
sControlName in this case is "cboEnoughMoney(0)" and I get an error that the control was not found.
EDIT: One of the issue's i'm having is trying to as above set the .listindex to -1, another one is where I actually try to get and set value to the combobox. In a function - i pass form name as parameter called frm.
In the code what has been done is this....
dim ctlData as string
If Frm.Controls(RS!CTRLname).ListIndex > 0 Then
CtlData = Frm.Controls(RS!CTRLname).Value
Else
CtlData = ""
End If
Any idea how I'd be able to do that with cboEnoughMoney(0)....
I assume I could follow your example and check
if instr(1,RS!CTRLname, "(")
but if there is, how would I refer to that particular control in frm
It is just enough to look in the VB Properties Window: if you search "cboEnoughMoney(0)" you will find "cboEnoughMoney"(0) (without double quotes). Still the name is the same as a non-array control.
So, it is perfectly legal to refer to a VB Control with Name and Index, no need for a controls loop here:
If isControlsArray Then
Set ctrl = Me.Controls(Name)(Index) '// array
Else
Set ctrl = Me.Controls(Name) '// non array
End If
You cannot use the (index) part in a lookup via .Controls.
You can loop them manually & given that you can safely assume any control name with a ( is an array member and thus will have an Index property match on that:
Private Function GetControl(ByVal name As String) As VB.Control
Dim pos As Long: pos = InStr(name, "(")
If pos = 0 Then
Set GetControl = Me.Controls(name) '// non array
Else
Dim index As Long
index = Val(Mid$(name, pos + 1)) '// get index #
name = Left$(name, pos - 1) '// get base name
For Each GetControl In Me.Controls
If (GetControl.name = name) Then
If (GetControl.index = index) Then Exit Function
End If
Next
Set GetControl = Nothing
End If
End Function
And then:
GetControl("cboEnoughMoney(1)").ListIndex = -1
I am using MSSQL ADO.NET and I need to sort order by employer code numercially although each order code has 2X letters in front of it.
For example:
HP1234
HP1233
HP1236
Essentially I am trying to seperate the numbers from the letters and order by either asc or desc just with the numbers to give some order. I wondered if anyone can advise on a good approach to do this withing an orderby clause.
SELECT *
FROM YourTable
ORDER BY CONVERT(int, RIGHT(employer_code, LEN(employer_code) - 2))
Note I did not add any erro checking, but this would help if the pattern changed etc. Even though this is C#, you can convert the code to VB.
void Main()
{
var arrayOfString = new string []{"HP1234","HP1233","HP1236"};
var pat =#"(?<name>\d+)";
Regex r = new Regex(pat, RegexOptions.IgnoreCase);
var orderedItems = arrayOfString.OrderBy(x=>{
var match = r.Match(x);
return match.Groups["name"].Value;
});
foreach (var item in orderedItems)
{
Console.WriteLine(item);
}
}
VB Code
Private Sub Main()
Dim arrayOfString = New String() {"HP1234", "HP1233", "HP1236"}
Dim pat = "(?<name>\d+)"
Dim r As New Regex(pat, RegexOptions.IgnoreCase)
Dim orderedItems = arrayOfString.OrderBy(Function(x) GetSortOrder(x,r))
For Each item As string In orderedItems
Console.WriteLine(item)
Next
End Sub
Function GetSortOrder(x , r)
Dim match = r.Match(x)
Return match.Groups("name").Value
End Function
I would like to create a file which will store properties containing desired values.
Each property has to be defined as an array of struct.
My current way of array of struct initialization:
classdef myClass < handle
properties(Constant)
myProp1 = struct(...
'Name', {'A','B'},...
'Value', {'1','2'});
end
end
How I wish to write my array of struct(which I feel is more clean and readable):
classdef myClass < handle
properties(Constant)
myProp1(1).Name = 'A';
myProp1(1).Value = 1;
myProp1(2).Name = 'B';
myProp1(2).Value = 2;
end
end
How should I go about achieving this?
Thanks
I think it's not possible to create structures in the properties definition like you proposed. (See my comment on your question). An alternative is to create the array of structs in the constructor. Use (SetAccess=private), so that the properties may not be changed from outside.
% myClass.m
classdef myClass < handle
properties(SetAccess=private)
myProp1 = struct
end
methods
function obj = myClass() % constructor
obj.myProp1(1).Name = 'A';
obj.myProp1(1).Value = 1;
obj.myProp1(2).Name = 'B';
obj.myProp1(2).Value = 2;
end
end
end
You can solve this issue by using object composition.
It seems that the property myProp in myClass represents something else. For sake of simplicity I will assume it is a person (you will need to adapt the example to cover your needs). You can create a Person class with properties Name, Value, ParentName and use it in your class. The property section in myClass would look like this:
myProp(1) = Person(name1, value1, parent_name1);
myProp(2) = Person(name2, value2, parent_name2);
...
myProp(N) = Person(nameN, valueN, parent_nameN);
Alternatively you can prepare your Person class to accept arrays as inputs:
names = {name1, name2, ..., nameN};
values = [value1, value2, ..., valueN];
parent_names = {pname1, pname2, ..., pnameN};
... %//possibly more code here
myProp = Person(names, values, parent_names);
and the class Person would take care of always keep them in the right order, provide setters and getters, etc.
A stub of a Person class for the first solution would look like this (a class accepting arrays would be longer):
classdef Person < handle
properties (Access = private)
name = '';
value = 0;
parent_name = '';
end
methods (Access = public)
function this = Person(name, value, parent_name)
this.SetName(name);
this.SetValue(value);
this.SetParentName(parent_name);
end
function SetName(this, name)
this.name = name;
end
function SetValue(this, value)
this.value = value;
end
function SetParentName(this, parent_name)
this.parent_name = parent_name;
end
end
end
There's nothing wrong with your original way of setting up myProp.
But if you're concerned just about readability, you could add a private static method called something like makeMyProp, which can be laid out as attractively as you want, which returns a filled out structure myProp.
Then, in the properties section, say myProp = myClass.makeMyProp;.
classdef myClass < handle
properties(Constant)
myProp1a = struct('Name','A','Value',1);
myProp1b = struct('Name','B','Value',2);
myProp1 = [myClass.myProp1a, myClass.myProp1b];
end
end
You could use enumeration(yes, this apparently exists in MATLAB).
An example usage would be:
classdef ExampleEnum < uint8 %// Can also be another datatype
enumeration
%// name value
A (1)
B (2)
end
end
Then MATLAB automatically uses the string or the value depending on how you use your enum object (this is mentioned in the documentation).
I'm trying to create an array of objects in vbscript, where each object has a string and a number as properties. The string is coming from a different array, and the number is incremented in the loop.
Here's the error occurring, on the line newValues(i) = (New Pet)(values(i), number):
...and here's my code:
Class Pet
Public objectName
Public objectNumber
' constructor here:
Public Default Function Init(name, number)
objectName = name
objectNumber = number
Set Init = Me
End Function
End Class
values = Array(_
"Cat",_
"Dog",_
"Bird"_
)
number = 3
ReDim newValues(uBound(values))
For i = 0 to uBound(values)
newValues(i) = (New Pet)(values(i), number)
number = number + 1
Next
Use Set when assigning objects.
Set newValues(i) = (New Pet)(values(i), number)