How to add values to System.Object Variable inside a foreach loop container with script task in SSIS? - ssis

I'm trying to add new values to a variable (System.Object) inside a foreach loop container that is using that variable. How can i do that ?
To understand my flow :
first script i'm adding a value to that variable and its working fine.
But inside the loop when i'm trying to add new values to that variable its not working :(
I've tried this 2 codes:
DataTable myDataTable = new DataTable("LISTA_CONTACTOS");
myDataTable.Columns.Add(new DataColumn("columnText", typeof(string)));
DataRow myDataRow = myDataTable.NewRow();
myDataRow["columnText"] = "1";
myDataTable.Rows.Add(myDataRow);
Dts.Variables["User::LISTA_CONTACTOS"].Value = myDataTable;
Dts.TaskResult = (int)ScriptResults.Success;
DataTable dataTable = (DataTable)Dts.Variables["LISTA_CONTACTOS"].Value;
dataTable.Columns.Add(new DataColumn("contact_id", typeof(string)));
DataRow newRow = dataTable.NewRow();
newRow["contact_id"] = "8535939";
dataTable.Rows.Add(newRow);
Dts.Variables["LISTA_CONTACTOS"].Value = dataTable;
Dts.TaskResult = (int)ScriptResults.Success;
Think its something like that ...
Can anyone help me ?

Related

How can I create a foreach loop with "Foreach From Variable Enumerator" in SSIS programmatically

I'm trying to create an SSIS package dynamically using DTS Runtime classes.
I'm trying to create a foreach loop using "Foreach From Variable Enumerator", where my variable contains an ArrayList with the necessary collection.
I'm unable to find a way through which i can set the variable (under enumerator configuration, as seen in VS) which will hold the collection for looping.
I'm not finding any options in forEachLoop.ForEachEnumerator. Nor am I able to cast forEachEnumeratorHost.InnerObject to an enumerator I want. I found on MSDN a class Microsoft.SqlServer.Dts.Runtime.Enumerators.FromVar.ForEachFromVarEnumerator. But I'm not able to find the FromVar class in Enumerators. Am i missing something grave?
Has anyone else done this? I find it difficult to believe that something which can be done so easily through Visual Studio UI, cannot be done programmatically.
Below is the code I have now...
ForEachLoop forEachLoop = p.Executables.Add("STOCK:FOREACHLOOP") as
ForEachLoop;
// Create a VariableMappings and VariableMapping objects.
ForEachVariableMapping forEachVariableMapping =
forEachLoop.VariableMappings.Add();
// Create a mapping between the variable and its value.
forEachVariableMapping.VariableName = #"User::CurrentTableName";
forEachVariableMapping.ValueIndex = 0;
ForEachEnumeratorInfo forEachEnumeratorInfo =
runtimeApp.ForEachEnumeratorInfos["Foreach From Variable Enumerator"];
ForEachEnumeratorHost forEachEnumeratorHost =
forEachEnumeratorInfo.CreateNew();
You are almost there...I think you are forgetting to set the ForEachEnumerator property of the forEachLoop object.
ForEachLoop forEachLoop = p.Executables.Add("STOCK:FOREACHLOOP") as ForEachLoop;
ForEachEnumeratorInfo forEachEnumeratorInfo = runtimeApp.ForEachEnumeratorInfos["Foreach From Variable Enumerator"];
ForEachEnumeratorHost forEachEnumeratorHost = forEachEnumeratorInfo.CreateNew();
//forEachEnumeratorHost.CollectionEnumerator = false; // true or false; set accordingly.
// cast the inner object to ForEachFromVarEnumerator
ForEachFromVarEnumerator = forEachEnumeratorHost.InnerObject as ForEachFromVarEnumerator;
// Now that you have the ForEachFromVarEnumerator, set its properties.
// For variable name, do not forget the variable's name space and the variable name (separated by ::)
ForEachFromVarEnumerator.VariableName = "var_namespace" + "::" + "var_name";
// finally.....
forEachLoop.ForEachEnumerator = forEachEnumeratorHost; // DO NOT FORGET THIS. Here you are setting what the actual enumerator would be
You can do like this:
Script task
Make sure MyList variable is Writeable
ArrayList NewList = new ArrayList();
NewList.Add("Ost");
NewList.Add("Hest");
Dts.Variables["User::MyList"].Value = NewList;
Dts.TaskResult = (int)ScriptResults.Success;
The first step is
Add an assembly reference to Microsoft.SqlServer.ForEachFromVarEnumerator.dll and then one can get access to the Microsoft.SqlServer.Dts.Runtime.Enumerators.FromVar.ForEachFromVarEnumerator class.
And then the rest of the answer is exactly what #Sam has mentioned above.

VB.net Autocomplete Textbox filter using mysql database as custom source

I'm Having a problem regarding to the autocomplete textbox. First I already made the autocomplete textbox work with mysql database as custom source but the default textfilter of autocomplete is "start with" not "contains". I want to change the textfilter to "contains", so that when I search any part of the string, the whole name which contains the searched word will appear in the autocomplete suggestions.
Can anyone help me fix my code?
This is the code i've done so far:
txtSearch.AutoCompleteMode = AutoCompleteMode.SuggestAppend
txtSearch.AutoCompleteSource = AutoCompleteSource.CustomSource
Dim DataCollection As New AutoCompleteStringCollection()
Dim query As String
sqlcon = New MySqlConnection
sqlcon.ConnectionString =
"server=localhost;userid=root;password=root;database=svfmemberlistdb"
Try
sqlcon.Open()
query = " SELECT Name FROM svfmemberlistdb.svfmemberlist "
sqlcmd = New MySqlCommand(query, sqlcon)
sqladr.SelectCommand = sqlcmd
sqladr.Fill(ds)
sqladr.Dispose()
sqlcon.Close()
For Each row As DataRow In ds.Tables(0).Rows
If row.ToString.Contains(txtSearch.Text) Then
DataCollection.Add(row(0).ToString())
End If
Next
Catch ex As Exception
End Try
txtSearch.AutoCompleteCustomSource = DataCollection
I quote here Mitja Bonca's answer on MSDN.
In this case, autocompletemode will just not do. Its code is not meant
for something like it.
You will have to do your own code, to do the filtering on each letter
press.
So I would suggest not to use autocompletemode, and get all the data
(names) into dataTable. When user presses some button ("1" for
example), you start with your filtering, by creating new Datatable
(leave the main one untached - so you can return back to all data when
clearing comboBox by backspace), with Copy() method - to create a full
copy of original one, and use Select method to do the filteing.
This should look something like by using % simbol on both sides of a
string - to filter inbetween - this is what you want!
DataTable AllNames = new DataTable();
//fill it up and leave it untouched!
//to filter comboBox with names that contains pressed characters do in
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
string name = string.Format("{0}{1}", comboBox1.Text, e.KeyChar.ToString()); //join previous text and new pressed char
DataRow[] rows = table.Select(string.Format("FieldName LIKE '%{0}%'", name));
DataTable filteredTable = AllNames.Clone();
foreach(DataRow r in rows)
filteredTable.ImportRow(r);
comboBox1.DataSource = null;
comboBox1.DataSource = filteredTable.DefaultView;
comboBox1.DisplayMember = "FieldName";
}
Reference
EDIT: This is of course a c# answer not VB.NET but it might be helpful to get the concept.

insert data in multiple table with one function in laravel

I'm trying to add values in multiple tables with the same function but I get an error that the id and product_id can't be null !! even though they are set. Here's my code:
$parentproduct=new Product();
$parentproduct->id=Input::get('id');
$insertedId = $parentproduct->id;
$parentproduct->save();
$product=new ProductsTranslation();
$product->id=Input::get('id');
$product->product_id =Input::get('insertedId');
$product->title=Input::get('title');
$product->content=Input::get('content');
$product->price=Input::get('price');
$product->description_title=Input::get('description_title');
$product->prod_info_title=Input::get('prod_info_title');
$product->prod_info=Input::get('prod_info');
$product->save();
Looks like you need to move a few things around here...
This $insertedId = $parentproduct->id; wont return a value until you've ran `->save().
Also, your second statement is trying to get an Input::('insertedId') but you're setting a variable above.
Try this:
$parentproduct = new Product();
$parentproduct->id = Input::get('id');
$parentproduct->save();
$insertedId = $parentproduct->id;
$product = new ProductsTranslation();
$product->id = Input::get('id');
$product->product_id = $insertedId;
$product->title = Input::get('title');
$product->content = Input::get('content');
$product->price = Input::get('price');
$product->description_title = Input::get('description_title');
$product->prod_info_title = Input::get('prod_info_title');
$product->prod_info = Input::get('prod_info');
$product->save();

Dynamically updating a table row in HTA (VBS)

After researching I can see that to dynamically update a table within a HTA, I need to add the tbody element. I can also see that then I need to use the appendchild function to add the necessary data / rows to the table.
I've done this and am trying to loop through an array ArrLogs using the code below
Dim i
i = 1
Set table = document.getElementById("maintable")
Set tbody = document.createElement("tbody")
table.appendChild(tbody)
Set trow = document.createElement("tr")
Set tcol = document.createElement("td")
ArrLogs = ReadLogs(computerasset.value)
Do Until i = UBound(ArrLogs)
tcol.innerHTML = ArrLogs(i)
trow.appendChild(tcol)
tbody.appendChild(trow)
table.appendChild(tbody)
i = i+1
Loop
The problem I'm having is that I'm only seeing the last value of my array appended to the table, almost as if I'm missing a command to save the append and it's overwriting the row as it runs through?
I'm very concious that this isn't tidy, or the correct way to loop through an array (should use for i = 1 to UBound(ArrLogs) etc) - I was testing different ways of doing things in case I was making an obvious mistake.
trow.appendChild(tcol) does not copy tcol to the row; it inserts a reference to it, meaning that you only ever have one tcol that you constantly overwrite, E.g. the code below would show B not A
Set p = document.createElement("p")
p.innerHTML = "A"
document.body.appendChild(p)
p.innerHTML = "B"
To fix this create new elements inside your loop:
Dim i: i = 0
Set tbody = document.createElement("tbody")
ArrLogs = ReadLogs(computerasset.value)
for i = lbound(ArrLogs) to ubound(ArrLogs)
Set trow = document.createElement("tr")
Set tcol = document.createElement("td")
tcol.innerHTML = ArrLogs(i)
trow.appendChild(tcol)
tbody.appendChild(trow)
Next
document.getElementById("maintable").appendChild(tbody)

How can I create a new DataGridView control for each new row in another datagridview in vb.net?

I have a DataGridView control (DataGridView6) that displays a list of managers. I want to generate a new DataGridView everytime I add a new manager to the list and put it in a specific place on my form.
EDIT:
say if i have a main datagridview, and i want to add another datagridview of the same size directly below it, how would i achieve this using the event handler method described in your answer below? im not sure if this is the most efficient way of displaying new members in the program though...
How do can I do this as simply as possible?
Use the DataGridView's "RowsAdded" event. Every time you add a new row (ie manager) to DataGridView6, have the event handler create a new DataGridView and place it where you want it.
It's hard to give a more detailed answer without the specifics of your implementation, but something like that should work.
EDIT - So something like this?
DataGridView dgv = new DataGridView();
dgv.Location = new Point(DataGridView6.Location.X,DataGridView6.Location.Y + <somevalue>);
If you need to keep adding them below this, you could just make a variable NextY that you increment each time you add a new one. You can store them all in a LinkedList or something similar so you can access them easily in order.
I'm not very good at VB, so I've written it in C# first:
DataGridView DataGridView6;
DataGridView DataGridView7;
DataGridViewRow CreateRow(object data) {
DataGridViewRow row = null;
int index = DataGridView6.Rows.Add();
row = DataGridView6.Rows[index];
// row.Cells[0] = something;
// basically, add your date
return row;
}
void DisplayManagerRow(DataGridViewRow row) {
DataGridView7.DataSource = null;
int columns = (DataGridView6.Columns != null) ? DataGridView6.Columns.Count : 0;
if ((row != null) && (0 < columns)) {
DataGridView7.Columns.Clear();
List<DataGridViewColumn> cols = new List<DataGridViewColumn>(columns);
for (int i = 0; i < columns; i++) {
DataGridViewColumn dgvCol = (DataGridViewColumn)DataGridView6.Columns[i].Clone();
DataGridView7.Columns.Add(dgvCol);
}
DataGridView7.Rows.Add(row);
}
}
Now, to try this in VB:
private DataGridView6 As DataGridView
private DataGridView7 As DataGridView
Private Function CreateRow(ByVal data As Object) As DataGridViewRow
Dim index As Int16 = DataGridView6.Rows.Add()
Dim row As DataGridViewRow = DataGridView6.Rows(index)
' row.Cells(0) = something
' basically, add your date
Return row
End Function
Private Sub DisplayManagerRow(ByVal row As DataGridViewRow)
DataGridView7.DataSource = Nothing
Dim columns As Int32 = 0
If Not (DataGridView6.Columns = Nothing) Then
columns = DataGridView6.Columns.Count
End If
If ((row Is Not Nothing) And (0 < columns)) Then
DataGridView7.Columns.Clear()
Dim cols As List<DataGridViewColumn> = new List<DataGridViewColumn>(columns)
For (Dim i As Int32 = 0; i < columns; i++)
Dim dgvCol As DataGridViewColumn = CType(DataGridView6.Columns(i).Clone(), DataGridViewColumn)
DataGridView7.Columns.Add(dgvCol)
Next For
DataGridView7.Rows.Add(row)
End If
End Sub
I can't even remember how to write a For loop in VB! Pathetic!
Does that get the point across, though?
Is this what you are trying to do?