Clean 2 Dimentional Array in VB.NET - windows

I declared my multidimentional array like this:
Dim invoice_discountitems(100, 1) As String
I Fill my array with this:
'Fill Array with items discounts
For i As Int16 = 0 To data_set.Tables("discount_items").Rows.Count - 1
invoice_discountitems(i, 0) = data_set.Tables("discount_items").Rows(i).Item("item_code")
invoice_discountitems(i, 1) = data_set.Tables("discount_items").Rows(i).Item("discountitem_average")
Next
Now how i can remove the filled items of this array?
Thanks in Advance

Because an array is statically sized, an empty array is the same as a freshly initialized array. So, if you want to clear the whole thing:
invoice_discountitems = New String(100, 1)
Or, if you wish to clear specific elements, use Array.Clear()
Array.Clear(invoice_discountitems, 1, 10)

Related

Make a macro to sort a row using a custom list in LibreOffice Calc

I need to sort a column containing cells with the following format : "TITLE text". I know the list of possible titles, but not the texts, so what I would like to do is sort the title in a custom order (for example : PLA, ARG, FHI, BRT) that is not alphabetical. The problem is that the title and the text are in the same cell.
So, for example, here is a screen of datas I might want to work on :
How can I sort this if the cells doesn't perfectly match the list members ?
And, if possible, how to do that using a macro and not manually ?
It's not very difficult. I will try to explain how this is done.
First of all, we need to figure out a way to transfer the range of cells to be sorted to the macro. There are different ways - write the address directly in the macro code, pass it as a parameter to the UDF, get it from the current selection. We use the third method - it is not the easiest to code, but it will work with any data sets.
The main difficulty when using the current selection is that the selection can be one single cell (nothing to sort), a range of cells (and may be several columns - how to sort this?) or several ranges of cells (this is if you hold down the CTRL key and select several unconnected ranges).
A good macro should handle each of these situations. But now we are not writing a good macro, we are getting acquainted with the principle of solving such problems (Since StackOfflow is a resource for programmers, the answers here help you write code yourself, and not get ready-made programs for free). Therefore, we will ignore a single cell and
multiple ranges - we will just stop execution of macro. Moreover, if there is more than one column in the selected range, then we will not do anything either.
Also, in case a full column is selected, we restrict the range to be sorted to the used area. This will sort the real data, but not the million empty cells.
The code that does all this looks like this:
Sub SortByTitles()
Dim oCurrentSelection As Variant
Dim oSortRange As Variant
Dim oSheet As Variant
Dim oCursor As Variant
Dim oDataArray As Variant
Dim sList As String
sList = "PLA,ARG,FHI,BRT"
oCurrentSelection = ThisComponent.getCurrentSelection()
Rem Is it one singl cell?
If oCurrentSelection.supportsService("com.sun.star.sheet.SheetCell") Then Exit Sub
Rem Is it several ranges of cells?
If oCurrentSelection.supportsService("com.sun.star.sheet.SheetCellRanges") Then Exit Sub
Rem Is this one range of cells? (It can be a graphic item or a control.
Rem Or it may not even be a Calc spreadsheet at all)
If Not oCurrentSelection.supportsService("com.sun.star.sheet.SheetCellRange") Then Exit Sub
Rem Is there only one column selected?
If oCurrentSelection.getColumns().getCount() <> 1 Then Exit Sub
Rem Is the current selection outside of the used area?
oSheet = oCurrentSelection.getSpreadsheet()
oCursor = oSheet.createCursor()
oCursor.gotoEndOfUsedArea(True)
oSortRange = oCursor.queryIntersection(oCurrentSelection.getRangeAddress())
If oSortRange.getCount() <> 1 Then Exit Sub
Rem Redim oSortRange as single range (not any ranges)
oSortRange = oSortRange.getByIndex(0)
Rem Get data from oSortRange
oDataArray = oSortRange.getDataArray()
Rem Paste sorted data to the same place:
oSortRange.setDataArray(getSorted(oDataArray, Split(sList,",")))
End Sub
The getSorted() function, which is mentioned in the last line of the procedure, must take two arrays as parameters — the values ​​of the cells to be sorted and the sort list — and return one array of sorted values.
One aspect of working with data from ranges of cells should be mentioned here. If in Excel after receiving data from the range we get a two-dimensional array, then in OpenOffice/LibreOffice we get a one-dimensional "array of arrays", each element of which is a one-dimensional array of cell values ​​of one row. Writing to a range is done from exactly the same structure, from an "array of arrays". The first parameter of the getSorted() function is oDataArray - just such an array of arrays, this will need to be taken into account when processing data.
What will getSorted() function do? It will build a "tree" sorted by Headers from the oDataArray values. In fact, this is not a tree - it is an ascending sorted array of all Headers and all values ​​with these Headers. The values ​​are also a sorted array. Then the function will select from the tree those Headings that are listed in the List and remove them from the tree. If, after all the actions, some elements still remain in the sorted tree, they will be displayed at the very end.
The function will accumulate the result in a separate array of the same size as the original one. In other words, the algorithm will use three times more memory than the original sorted range - source data, a tree and result array. The function will accumulate the result in a separate array of the same size as the original one. In other words, the algorithm will use three times more memory than the original sorted range - source data, a tree and result array.
You can try to save resources and write the results directly to the original array. But I strongly advise against doing this.
The fact is that an array cell may contain not a value, but a reference to a value, and in the case of inaccurate coding, you will not get a large sorted array, but a large array of the same value (the last cell).
I deliberately do not comment on all the following code - if you can read and understand this without comment, then you will understand how actions are programmed to process data from ranges:
Function getSorted(aData As Variant, aList As Variant) As Variant
Dim aRes As Variant
Dim i As Long, pos As Long, j As Long, k As Long, m As Long, uB As Long
Dim aTemp As Variant
aTemp = Array()
ReDim aRes(LBound(aData) To UBound(aData))
For i = LBound(aData) To UBound(aData)
pos = InStr(aData(i)(0), " ")
If pos > 0 Then
AddToArray(Left(aData(i)(0),pos-1), aData(i)(0), aTemp)
Else
AddToArray(aData(i)(0), aData(i)(0), aTemp)
EndIf
Next i
m = LBound(aData) - 1
For i = LBound(aList) To UBound(aList)
k = getIndex(aList(i), aTemp)
If k > -1 Then
uB = UBound(aTemp) - 1
For j = LBound(aTemp(k)(1)) To UBound(aTemp(k)(1))
m = m + 1
aRes(m) = Array(aTemp(k)(1)(j))
Next j
For j = k To uB
aTemp(j) = aTemp(j+1)
Next j
ReDim Preserve aTemp(uB)
EndIf
Next i
For k = LBound(aTemp) To UBound(aTemp)
For j = LBound(aTemp(k)(1)) To UBound(aTemp(k)(1))
m = m + 1
aRes(m) = Array(aTemp(k)(1)(j))
Next j
Next k
getSorted = aRes
End Function
To build a sorted tree, two subroutines are used - AddToArray() and InsertToArray(). They are very similar - the first eight lines are a normal binary search, and the remaining 10-12 lines are actions when an element is not found at the end of the array, when it is found and when it is not found in the middle of the array:
Sub AddToArray(key As Variant, value As Variant, aData As Variant)
Dim l&, r&, m&, N&, i&
l=LBound(aData)
r=UBound(aData)+1
N=r
While (l<r)
m=l+Int((r-l)/2)
If aData(m)(0)<key Then
l=m+1
Else
r=m
EndIf
Wend
If r=N Then
ReDim Preserve aData(0 To N)
aData(N) = Array(key, Array(value))
ElseIf aData(r)(0)=key Then
InsertToArray(value, aData(r)(1))
Else
ReDim Preserve aData(0 To N)
For i = N-1 To r Step -1
aData(i+1)=aData(i)
Next i
aData(r) = Array(key, Array(value))
EndIf
End Sub
Sub InsertToArray(key As Variant, aData As Variant)
Dim l&, r&, m&, N&, i&
l=LBound(aData)
r=UBound(aData)+1
N=r
While (l<r)
m=l+Int((r-l)/2)
If aData(m)<key Then
l=m+1
Else
r=m
EndIf
Wend
If r=N Then
ReDim Preserve aData(0 To N)
aData(N) = key
Else
ReDim Preserve aData(0 To N)
For i = N-1 To r Step -1
aData(i+1)=aData(i)
Next i
aData(r) = key
EndIf
End Sub
The getIndex() function uses the same binary search. It will return the index of the element in the array if it can find it, or -1 otherwise:
Function getIndex(key As Variant, aData As Variant) As Long
Dim l&, r&, m&, N&
l=LBound(aData)
r=UBound(aData)+1
N=r
While (l<r)
m=l+Int((r-l)/2)
If aData(m)(0)<key Then
l=m+1
Else
r=m
EndIf
Wend
If r=N Then
getIndex = -1
ElseIf aData(r)(0)=key Then
getIndex = r
Else
getIndex = -1
EndIf
End Function
And that's all that is needed to solve the task:
Demo file with code - SortByTitle.ods

QTP/UFT - Storing Multiple Arrays In An Array

I have a function that imports a sheet to the global sheet and then loops through the columns and rows to create an array.
Code
Public Function importArray()
DataTable.ImportSheet "location","Lists", "Global"
rowCount = DataTable.GetSheet(dtGlobalSheet).GetRowCount -1
columnCount = DataTable.GetSheet(dtGlobalSheet).GetParameterCount
ReDim myArray(-1)
For x = 1 to columnCount Step 1
For i = 0 to rowCount Step 1
ReDim Preserve myArray(UBound(myArray) + 1)
myArray(i) = Datatable.Value(x, dtGlobalSheet)
Datatable.SetNextRow
Next
MsgBox Join(myArray, vbNewLine)
Next
End Function
So now that I know I can get the columns into an array, I need to store each array individually.
For example:
Main array = myArray(i)
Call importArray() to get array
Column count = 2
Column names = Name, Surname
Store array into array variable with name as column name
Populate myArray() with stored arrays
myArray(Name(), Surname())
The reason I want to do this is because I have a function that will need to reference these arrays to look for a value in the array then do some logic. While I know that I can just create arrays one by one, the problem is that I might have 20 arrays to use, in which case the code will become really bulky.
Perhaps there is a better way to do what I am thinking of doing, but otherwise, help on this would be really appreciated.
Use multidimensional arrays
'Declare a Dynamic Array
Dim arrData()
' Make it a multidimensional array
ReDim Preserve arrData(rowCount, colCount)
For Loop row
For Loop col
arrData(row, col) = ...
Next
Next
column names as array indexes is not okay - that is a dictionary (Map) already

Iterate over all selected rows of SSDBGrid to fill an array

I need to iterate over all of the selected rows in an SSDBGrid. Then, I need to get the value in the current row and populate the relevant place in the array with this value.
I've been attempting to do this with the code below:
Dim i As Integer
i = 0
Dim nomCode(Grd_Nominal.SelBookmarks.Count) As String ' This is my array.
Do While Grd_Nominal.SelBookmarks <> 0
nomCode(i) = Grd_Nominal.SelBookmarks(0)
If Grd_Nominal.SelBookmarks.Count > 0 Then
Grd_Nominal.SelBoomarks(0).Remove
End If
i = i + 1
Loop
However, nomCode(i) is always being filled as nomCode(i) = "??"
Why is it inserting "??", and how can I fix this to insert the value of the current row?
You need to first of all re-think how you're declaring your array.
Dim nomCode() As String
ReDim nomCode(Grd_Nominal.SelBookmarks.Count - 1) As String
This is because when declaring an array you need to pass in a constant as the length. ReDim doesn't, so this will go partly towards solving the issue.
Dim x As Integer
Dim bk As Variant
For x = 0 to Grd_Nominal.Rows.Count - 1
bm = Grd_Nominal.SelBookmarks(x)
nomCode(x) = Grd_Nominal.Columns("Your_Column").CellValue(bm)
Next
This should sort the rest of the issue, I think.

Iterate through a PlatonScript array

I am developing on the top of the jPlaton platform and I want to declare a 10-element array of integers in PlatonScript.
Then, I want to assign a number to each array position, lets say numbers 1 to 10.
Finally, I want to iterate through this array and calculate and print the double of each array element.
Array
|1|2|3|4|5|6|7|8|9|10|
Output
|2|4|6|8|10|12|14|16|18|20|
How do I do those "for" loops?
Thanks
#ind:INTEGER
#arr:INTEGER[]
#ind=1
LOOP
setIndex arr #ind
IF (#ind>10)
BREAK
#arr = #ind
#ind=#ind+1
ENDLOOP
#dint:INTEGER
#dint=0
#ind=1
LOOP
setIndex arr #ind
IF (#ind>10)
BREAK
#dint=2*#arr
#ind=#ind+1
HTML
<p>#dint</p>
ENDHTML
ENDLOOP
Useful array methods
setIndex ObjectName IndexValue
Used in variable of array type
Set the current index of the variable
If index set to -1 then method returns the element count
of the array If index set to 0 then current index set to the last plus one (next empty). If index set to a number smaller or equal to the element count the currennt index is set to the specified number First position index is 1, next is 2 and so on. After we set the current array index we are able to access the current array element using the name of the variable as it was a simple (elementary) one
clear ObjectName
Clear the value of the variable. For arrays all the elements of the array are cleared and the array size is set to 0.
sort ObjectName
Sort the elements of an array type variable

Numpy savetxt loop

Using Numpy, I am going to split an array of dimension (557124,2), dtype = "S10", in 6 subarrays using:
sub_arr = np.split(arr, 6)
Now I would like to use a for loop on savetxt and save the 6 subarrays to 6 .txt files.
I tried:
for i in sub_array:
np.savetxt(("Subarray", i, ".txt"), sub_array[i], fmt='%s')
There are 2 problems:
It's incorrect to say in sub_array. I should use range(5) but I want to make it adaptable to any number of sub arrays.
I thought I could use a sort of "paste" as in R when I did ("Subarray", i, ".txt"). Is there anything alike in Numpy?
Any idea?
From what I've understood
sub_arr = np.split(arr, 6)
returns a list of 6 numpy arrays. Then you can use enumerate to get each array and its index
fname_template = "Subarray.{i}.txt"
for i, sarr in enumerate(sub_arr):
np.savetxt(fname_template.format(i=i), sarr, fmt='%s')
To create the file name I've used the new string formatting. Otherwise you can concatenate strings with + as "Subarray."+str(i)+".txt", but you have to make sure that all the elements that you concatenate are strings.

Resources