How to arrange dates from old to new in vb scripting - vb.net

I'm developing a macro using extra attachmate. we have a 3rd party tool called CSS from where macro fetches required data. Now I'm trying to arrange dates from old to new.
Firstly I have changed date(10/01/14) to number(140110) and then extracted all values into array. From array is there any Function to sort the numbers or should i compare each value manually in loop?
After comparing the records from array, I have to write this data in different columns of single row.
IF my approach is incorrect then please suggest me correct way.
Thanks,
Yaswanth

Your question talks about a lot of different things. I assume that you want to sort an array of integer. To do that you can use the Sort function.
Dim arr(2) As Integer
arr(0) = 140110
arr(1) = 130110
arr(2) = 150110
Array.Sort(arr)

Related

cannot get value from a cell in libreoffice 6.4.3.2 basic

I am new to libreoffice basic, i have experience with VBA but this libreoffice is different.
I just want to get cell value but it always return zero value to me while the actuall cell can be text or number.
Here is a partial of my simple code.
Sub test_moved()
Dim Doc As Object
'worksheet
Dim sh_village As Object
Dim sh_cbc As Object
sh_village = ThisComponent.CurrentController.getActiveSheet()
'sh_village = Doc.Sheets.getByName("VillageFinal")
'sh_village = Doc.Sheets(1)
Msgbox(sh_village.getCellrangeByName("B2").getValue())
Msgbox(sh_village.getCellrangeByName("B2").Value)
Msgbox(sh_village.getCellByPosition(1,1).Value)
msgbox("The process is completed.")
End Sub
Do we need to do prior task before start coding?
The code works correctly for numeric values. However, for strings, including strings that look like a number, it will display 0 because there is no numeric value.
What you probably want instead is:
MsgBox(sh_village.getCellRangeByName("B2").getString())
Also check out Format -> Cells -> Number to see how the data is displayed in the cell. And be on the lookout for a single quote at the front of the value in the formula bar (for example '42), because that means it is a string. Delete the quote to make it a number.
i have experience with VBA but this libreoffice is different.
Yes, LibreOffice Basic is a different language from VBA and the LibreOffice API is very different from the MS Office API. Knowing that will help you use it more effectively. If possible, avoid Option Compatible, because it won't fix most problems and will only muddy the waters.

Referring to a variable in a variable

This is probably quite simple to do but I am very new to visual basic so please bear with me.
I know similar questions have been asked, but none of them seem to answer my question. I have an array created earlier, and want to randomly choose one value and change it.
I have two random number generators ('GeneratorP1' and 'GeneratorP2'), which are added to some text a create a variable name which is stored in Loc1:
Dim Loc1 As String
Loc1 = "th" & GenerateP1() & "(" & GenerateP2() & ")"
eg: th5(4) is stored in Loc1
How would I go about changing the value of th5(4)?
EDIT: I have 5 arrays (th1, th2, th3, th4, th5), with indexes up to 4
If I'm understanding your question correctly (which I'm not sure I am), you're wanting to use the string stored in variable Loc1 as a variable name?
You said you created an array earlier, so why do you need to randomly generate the variable (GenerateP1) and the index (GenerateP2)? If you have a single array, can't you use randomly pickthe index, then assign whatever value you want to it?
th5(GenerateP2()) = "my value"
If you had multiple arrays (th1, th2, th3, etc.) I would suggest using a Dictionary to randomly pick which array to use. Alternatively you could use a multidimensional array and generate both indexes
th(GenerateP1(), GenerateP2()) = "my value"
If possible, you should consider using a List instead of an Array.
Instead of having multiple arrays, use a 2-dimensional array
Dim th(5,4)
So instead of trying to reference th1(3), you could use th(1,3) or th5(2) would be th(5,2)

ListBox or Combobox ADODB imported Decimal items invisible in the list

I have encountered this problem several times already and have been able to work around it till now. Also the almighty search engines didn't help me.
The problem is that when I have populated a listbox or combobox from a ADODB recordset all Decimal data elements are not visible in the box, for example with the following (conn is a ADODB connection):
Private Sub GetFilteredRecords()
Dim strSQL As String
Dim arr As Variant
'create the SQL
strSQL = "SELECT * FROM vwStandard_Fee2"
'execute the SQL and fill the rs ( rsFiltered )
Set rsFiltered = conn.Execute(strSQL)
'Apply recordset to the listbox on the form
If Not (rsFiltered.EOF = True And rsFiltered.BOF = True) Then
arr = rsFiltered.GetRows()
With lbDeeper
.ColumnCount = rsFiltered.Fields.Count
.List = TransposeArray(arr)
End With
With cbDeeper
.ColumnCount = rsFiltered.Fields.Count
.List = TransposeArray(arr)
End With
End If
End Sub
Above contains 6 columns of Ids (all show Type = Variant/Decimal), of which the containing values are all not "shown" for some strange reason. Only the String and Date columns are shown normally, the Decimals are there but empty!
Here some snippets:
Now in case of a combo box I can get one column's value shown if their column the BoundColumn when I select that listitem, but only in the value fo the combobox (so still not in the list).
My initial workaround was to convert them into String values before adding to the Listbox/Combobox, in this case however I want to directly link the query result to the Box.List without looking at the details. And thus I am looking for a solution in stead of a work around.
In short: my numerical field items are invisible BY DEFAULT for some strange reason. Workaround was to make the items String values. I am now looking for a solution for this bug/problem instead:
What is causing this?
How to solve it?
So all string data is appearing? And,only numerics don't appear?
Then you may want to convert your numerics to strings and pass it to your list, combo boxes.
Which you have already done I noticed.
Now for any reason if your max number of rows and length of array/recorders row count doesn't match it could also cause an issue. However it seems your setting rows of combobox using recordset row count. Instead of using an array can you try to iterate over the recordset to populate the combobox? yes this is not performance friendly, buy guess what we need it to work without bugs before optimizing. ;-)
Have you bound your combobox to the recordset? Can you confirm if your array is single dimension and it has data to feed to the box?
You may try to populate the listbox using a saved query in the DB to if the issue still persists.
However, list boxes and combo boxes based on SQL statements are slower than
list boxes and combo boxes based on saved queries.
So can you try the following to set rowsource property? Make sure to test on both number,and test columns. As well as on old combo box and new one.
Rowsource->build query->
sqlview copy to rowsource property box->
delete or don't save that above built query since you already have SQL statement.
Just wanted you to try out possibilities to narrow down the issue.
UPDATING ANSWER WITH MOST POSSIBLE ISSUE AND SOLUTIONS
As per my comments, they mainly given assuming you had issues populating listbox/combobox
I forgot to ask something very very important, have you declared
Option Base 1 to make sure to avoid losing one of the array's column
values if you are dumping 2D array...? because you do not have any
explicit declartion for the array you are using to dump data into the
listbox.......... :)
Make sure your Listbox is enabled to show multi column data.
*So you have three choices, *
Option Base 1
ReDim your array and do looping to fill it and dump it into .list.
Since ReDim array need you to anyway loop through, you may just as well
use the recorset iself to add the data.
You seem to have a dimension issue with the array which is not declared but transposed from recordset and then to listbox/combobox. So your undeclared array is not populating multi-columns properly. That could be the reason it works when you declare array proeprly.......
Infact in your comment you have said so,
When I create an array in my code and populate it in my code (entry by
entry) it will show without any problem – K_B 14 mins ago
OK after going through various possible causes it seems to be the case that:
VBA has no Decimal Variant Type of its own.
VBA can handle Decimal from within a variable declared as Variant (thus becoming a Variant/Decimal)
This normally doesn't stop your program from working, but in Controls like Listbox and Combobox the Type Variant/Decimal is not interpretable and thus wont draw that specific entry.
For example populate a listbox called lbHigher with this:
Private Sub ListBoxProblem()
Dim tempArray(2, 2) As Variant
tempArray(0, 0) = "A"
tempArray(0, 1) = 1
tempArray(0, 2) = 1.1
tempArray(1, 0) = "B"
tempArray(1, 1) = CStr(CDec(5.2))
tempArray(1, 2) = 2.3
tempArray(2, 0) = "C"
tempArray(2, 1) = DateSerial(2012, 12, 13)
tempArray(2, 2) = 100
tempArray(3, 0) = "D"
tempArray(3, 1) = -1
tempArray(3, 2) = CDec(5.2)
lbHigher.ColumnCount = 3
lbHigher.List = tempArray
End Sub
Everything works fine except for the CDec(5.2). The CStr(CDec(5.2)) works fine as well as VBA will first have converted the Decimal to String before the Listbox gets to get it.
So either: Dont let the SQL generate any Decimal output OR convert any Decimal output to Single/Double/String/Integer/Long in VBA before handing it to the Listbox.

SSIS custom script: loop over columns to concatenate values

I'm trying to create a custom script in SSIS 2008 that will loop over the selected input columns and concatenate them so they can be used to create a SHA1 hash. I'm aware of the available custom components but I'm not able to install them on our system at work.
Whilst the example posed here appears to work fine http://www.sqlservercentral.com/articles/Integration+Services+(SSIS)/69766/ when I've tested this selected only a few and not all columns I get odd results. The script only seems to work if columns selected are in sequential order. Even when they are in order, after so many records or perhaps the next buffer different MD5 hashes are generated despite the rows being exactly the same throughout my test data.
I've tried to adapt the code from the previous link along with these articles but have had no joy thus far.
http://msdn.microsoft.com/en-us/library/ms136020.aspx
http://agilebi.com/jwelch/2007/06/03/xml-transformations-part-2/
As a starting point this works fine to display the column names that I have selected to be used as inputs
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
For Each inputColumn As IDTSInputColumn100 In Me.ComponentMetaData.InputCollection(0).InputColumnCollection
MsgBox(inputColumn.Name)
Next
End Sub
Building on this I try to get the values using the code below:
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Dim column As IDTSInputColumn100
Dim rowType As Type = Row.GetType()
Dim columnValue As PropertyInfo
Dim testString As String = ""
For Each column In Me.ComponentMetaData.InputCollection(0).InputColumnCollection
columnValue = rowType.GetProperty(column.Name)
testString += columnValue.GetValue(Row, Nothing).ToString()
Next
MsgBox(testString)
End Sub
Unfortunately this does not work and I receive the following error:
I'm sure what I am trying to do is easily achievable though my limited knowledge of VB.net and in particular VB.net in SSIS, I'm struggling. I could define the column names individually as shown here http://timlaqua.com/2012/02/slowly-changing-dimensions-with-md5-hashes-in-ssis/ though I'd like to try out a dynamic method.
Your problem is trying to run ToString() on a NULL value from your database.
Try Convert.ToString(columnValue) instead, it just returns an empty string.
The input columns are not guaranteed to be in the same order each time. So you'll end up getting a different hash any time the metadata in the dataflow changes. I went through the same pain when writing exactly the same script.
Every answer on the net I've found states to build a custom component to be able to do this. No need. I relied on SSIS to generate the indexes to column names when it builds the base classes each time the script component is opened. The caveat is that any time the metadata of the data flow changes, the indexes may change and need to be updated by re-opening and closing the SSIS script component.
You will need to override ProcessInput() to get store a reference to PipelineBuffer, which isn't exposed in ProcessInputRow, where you actually need to use it to access the columns by their index rather than by name.
The list of names and associated indexes are stored in ComponentMetaData.InputCollection[0].InputColumnCollection, which needs to be iterated over and sorted to guarantee same HASH every time.
PS. I posted the answer last year but it vanished, probably because it was in C# rather than VB (kind of irrelevant in SSIS). You can find the code with all ugly details here https://gist.github.com/danieljarolim/e89ff5b41b12383c60c7#file-ssis_sha1-cs

Using Large Arrays in VB.NET

I want to extract large amounts of data from Excel, manipulate it and put it back. I have found the best way to do this is to extract the data from an Excel Range in to a large array, change the contents on the array and write it back to the Excel Range.
I am now rewriting the application using VB.NET 2008/2010 and wish to take advantage of any new features.
Currently I have to loop through the contents of the array to find elements with certain values; also sorting large arrays is cumbersome. I am looking to use the new features, including LINQ to manipulate the data in my array.
Does anybody have any advice on the easiest ways to filter / query, sort etc. data in a large array. Also what are the reasonable limits to the size of the array?
~Many Thanks
Although you have a multi-pronged question, I've chosen to answer the part about manipulating arrays using LINQ...
Edit - LINQ against 2D array, VB.NET
System.Array (from where all arrays are derived) supports an extension method for .AsQueryable() which means you can process a 2D array with LINQ directly like so:
Option Infer On
Option Strict Off
Public Class DataProcessor
'something like this came from Excel, maybe a Range
Dim arrValues2D(,) As String = { _
{"1", "2", "3"}, _
{"100", "99", "98"}, _
{"2", "3", "4"} _
}
Private Sub FindLargeNumbers()
'LINQ against 2D array elements
Dim query = From v In arrValues2D Where (Int32.Parse(v) > 50 And Int32.Parse(v) < 101) Select CStr(v)
For Each thing As String In query
'do stuff
Console.Write(thing + ",")
Next
End Sub
End Class
Original thoughts
(pretty much deprecated since the above solution)
You could Implement IEnumerable(Of T) and IEnumerator(Of T) in Visual Basic to "flatten" your 2D array (effectively return its values one at a time as if it were a 1D array) and perform operations with the values using LINQ.
Depending on the data type of array elements, in order to write back to them, you might need to wrap each value in something so you can reference the original element instead of a copy of its value.
This is just a general plan to allow you to use LINQ and "new features" against a large efficient 2D array that you already have from Excel.
If you want any performance, you have to stick with extracting the data into arrays, manipulating the arrays, then writing back the data into the range. The performance benefit is significant. I have tested and it is hundreds of times faster.
I do all my array manipulation with custom functions. I do not believe LINQ can compare to my custom functions in speed. What LINQ does bring to the table is flexibility and readability and maintainability. If you design custom array manipulation functions with LINQ principles in mind, then you should be able to take advantage of LINQ without giving up performance. For instance, I had a Median array function. I converted it to a Median extension function that accepted a sequence of doubles then used LINQ over the array to call the Median function.
<Extension()> Public Function Median(ByVal source As IEnumerable(Of Double)) As Double
As in;
Dim m = Aggregate v In arrValues2D Into Median(CDbl(v))
I checked this out of curiosity, and I don't think LINQ is the way to go. I assume that you are reading named ranges into "rectangular" arrays of objects. If that's the case, the bad news is, a rectangular array is non-enumerable and non-queryable, which means you can't execute a LINQ query against it. See the following discussion for details:
querying 2-dimension array with LINQ I stand corrected. Thx to jdk and AMissico for taking the time to explain!