Remove trailing char when congregating after merging text in multiple columns to one - arrays

I'm trying to congregate text in multiple columns into one column in google sheets. I'm using the following formula. It works but unless there is an item in column E I get a comma at the end of any entry that was in B,C, or D.
=ARRAYFORMULA(IF(ROW(G:G)=1,"Events", IF(A:A="","", B:B) & IF(B:B<>"",", "&C:C, C:C) & IF(C:C<>"",", "&D:D, D:D) & IF(D:D<>"",", "&E:E, E:E)))
How to I check to see if there are no entries after and thus remove the trailing comma.
For exmaple, this works:
event1, event2, event3, event 4
but if there is not an item in the last column (E) then it looks like this
event1, event2,

try:
=ARRAYFORMULA(REGEXREPLACE(TRIM(IF(ROW(G:G)=1, "Events",
IF(A:A="",, B:B)&
IF(B:B<>"", ", "&C:C, C:C)&
IF(C:C<>"", ", "&D:D, D:D)&
IF(D:D<>"", ", "&E:E, E:E))), ",$", ))

Related

Combine 2 rows of CSV file in SSIS

I have one CSV file where the information is spread on two lines
Line 1 contains Name and age
Line 2 contains detail like address, city, salary, occupation
I want to combine 2 rows to insert it in a database.
CSV file :
Raju, 42
12345 west andheri,Mumbai, 100000, service
In SQL Server I can do by using cursor. But I have to do in SSIS.
For a similar case, i will read each line as one column and use a script component to fix the structure. You can follow my answer on the following question. It contains a step-by-step guide:
SSIS reading LF as terminator when its set as CRLF
I like using a script component in order to be able to store data from a different row in this case.
Read the file as a single column CSV into Column1.
Add script component and add a new Output called CorrectedOutput and define all columns from both rows. Also, mark Column1 as read.
Create 2 variables outside of row processing to 'hold' first row
string name = string.Empty;
string Age = string.Empty;
Use a split to determine line 1 or line 2
string[] str = Row.Column1.Split(',');
Use an if to determine row 1 or 2
if(str.Length == 2)
{
name = str[0];
age=str[1];}
else
{
CorrectedOutputBuffer.AddRow();
CorrectedOutputBuffer.Name = name; //This uses the stored value from prior row
CorrectedOutputBuffer.Age = age; //This uses the stored value from prior row
CorrectedOutputBuffer.Address = str[0];
CorrectedOutputBuffer.City = str[1];
CorrectedOutputBuffer.Salary = str[2];
CorrectedOutputBuffer.Occupation = str[3];
}
The overall effect is this...
On Row 1, you just hold the data in variables
On Row 2, you write out the data to 1 new row.

Calculate Sum and Insert as Row

Using SSIS I am bringing in raw text files that contain this in the output:
I use this data later to report on. The Key columns get pivoted. However, I don't want to show all those columns individually, I only want to show the total.
To accomplish this my idea was calculate the Sum on insert using a trigger, and then insert the sum as a new row into the data.
The output would look something like:
Is what I'm trying to do possible? Is there a better way to do this dynamically on pivot? To be clear I'm not just pivoting these rows for a report, there are other ones that don't need the sum calculated.
Using derived column and Script Component
You can achieve this by following these steps:
Add a derived column (name: intValue) with the following expression:
(DT_I4)(RIGHT([Value],2) == "GB" ? SUBSTRING([Value],1,FINDSTRING( [Value], " ", 1)) : "0")
So if the value ends with GB then the number is taken else the result is 0.
After that add a script component, in the Input and Output Properties, click on the Output and set the SynchronousInput property to None
Add 2 Output Columns outKey , outValue
In the Script Editor write the following script (VB.NET)
Private SumValues As Integer = 0
Public Overrides Sub PostExecute()
MyBase.PostExecute()
Output0Buffer.AddRow()
Output0Buffer.outKey = ""
Output0Buffer.outValue = SumValues.ToString & " GB"
End Sub
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Output0Buffer.AddRow()
Output0Buffer.outKey = Row.Key
Output0Buffer.outValue = Row.Value
SumValues += Row.intValue
End Sub
I am going to show you a way but I don't recommend adding total to the end of the detail data. If you are going to report on it show it as a total.
After source add a data transformation:
C#
Add two columns to your data flow: Size int and type string
Select Value as readonly
Here is the code:
string[] splits = Row.value.ToString().Split(' '); //Make sure single quote for char
int goodValue;
if(Int32.TryParse(splits[0], out goodValue))
{
Row.Size = goodValue;
Row.Type = "GB";
}
else
{
Row.Size = 0;
Row.Type="None";
}
Now you have the data with the proper data types to do arithmatic in your table.
If you really want the data in your format. Add a multicast and an aggregate and SUM(Size) and then merge back into your original flow.
I was able to solve my problem in another way using a trigger.
I used this code:
INSERT INTO [Table] (
[Filename]
, [Type]
, [DeviceSN]
, [Property]
, [Value]
)
SELECT ms.[Filename],
ms.[Type],
ms.[DeviceSN],
'Memory Device.Total' AS [Key],
CAST(SUM(CAST(left(ms.[Value], 2) as INT)) AS VARCHAR) + ' GB' as 'Value'
FROM [Table] ms
JOIN inserted i ON i.Row# = ms.Row#
WHERE ms.[Value] like '%GB'
GROUP BY ms.[filename],
ms.[type],
ms.[devicesn]

Replace NULL in SSIS

I'm using 2 lookups in ssis for 2 tables. If a column is null in the other table, im going to use the other value and vice versa.
how to implement this one?
Here is one idea how to do it:
Lookup component:
Add the column of the other table as a new column (like 'column2').
After the lookup put a derived column:
Derived column name will be your initial column, set it to replace the original column.
In the expression put:
REPLACENULL(column,column2)
Use your look up component, and add the new column (Correspondant value in Lookup Table)
Assuming that your columns names are LookupColumn1 and LookupColumn2 And OutColumn is the expected output column:
First Method
Add a script component
Mark LookupColumn1 and LookupColumn2 as Input
Add an Output Column OutColumn ( DataType: DT_STR or DT_WSTR)
In your Script Write the following Code (inside ProcessInputRow Sub) :
Public Overrides Sub InputBuffer0_ProcessInputRow(ByVal Row As InputBuffer0)
If Not Row.LookUpColumn2_IsNull AndAlso _
Not String.IsnullOrEmpty(Row.LookUpColumn2.Trim) Then
Row.OutColumn = Row.LookUpColumn2.Trim
ElseIf Not Row.LookupColumn1_IsNull AndAlso _
Not String.IsnullOrEmpty(Row.LookupColumn1.Trim) Then
Row.OutColumn = Row.LookupColumn1.Trim
Else
Row.OutColumn_IsNull = True
End If
End Sub
Script Logic: If LookupColumn2 is not null or empty, it's value is assigned to OutColumn , if LookupColumn2 is null or empty we checks the value of LookupColumn1 : if it is not null or empty, it's value is assigned to OutColumn , else OutColumn is NULL
Second Method
Create a derrived column with the following expression
REPLACENULL(LookupColumn2,LookupColumn1)
Read more about REPLACENULL In this MSDN article

how to copy excel column data to another worksheet and do text-to-columns programatically

I have a working copy of an application that will open workbooks/sheets and copy data succesffully between the two then saves but I need to parse some data as I copy it into another cell.
I was thinking..
~ create array
~ get all values in xlSourceFile.worksheets("sheet1") and store into an array
~ parse through the array extracting the data I need (text-to-column programatically)
~ write the array data to two specific columns in excel worksheet
the data I am trying to parse is Firstname / Lastname - Email and I want this as a result:
Joe Shmoe to go into one column // Joe Shmoes Email to another column.
I am writing this in vb.net using the imports Microsoft.Office.Interop to manipulate Excel.
Excuse the formatting, I'm new to SO. This is VBA but I believe the general logic will work. It assumes that the email address has no space padding after it. It searches backward on the raw combined string for the first blank space and flags that as the start of the email address (end of the name).
It loops out when the next cell is empty.
The data is assumed to look like this:
"First Name Last Name myaddress#example.com"
For Each cell In Worksheets("Sheet1").Range("A:A")
i = i + 1
If cell = "" Then GoTo loopout
rawstring = cell.Value
'rawString = "First Name Last Name myaddress#example.com"
emailStartPosition = InStrRev(rawstring, " ")
myname = Left(rawstring, emailStartPosition)
myemail = Right(rawstring, Len(rawstring) - emailStartPosition)
Worksheets("Sheet1").Range("B" & i).Value = myname
Worksheets("Sheet1").Range("C" & i).Value = myemail
Next
loopout:
End Sub
Column B will have the name and Column C will have the email address.

Trouble adding elements to a table (array in Lua)

I am attempting to create a table to serve as a small database for users:
users = {}
function create_new_user()
print("Enter a unique user name (up to 12 letters): ")
local name = io.read()
if #name > 12 then
print ("That name is too long.")
return create_new_user()
elseif users[name] then
print ("That name is already in use.")
return create_new_user()
else
table.insert(users, 1, name)
print("Your new user name is: ", users[name])
end
end
I understood from the manual that the line
table.insert(users, 1, name)
would insert the string value of name as an element of the users array. This is not the case-- whenever I run the script I get the following output:
Your new user name is: nil
You insert the element into the table, but you are trying to retrieve the value indexed by the value of name, which is not what you stored (you are using users[name] instead of users[1]). You can probably do something like this:
table.insert(users, name)
print("Your new user name is: ", name)
Note that table.insert(users, 1, name) may not do what you expect as this will prepend elements to the table. If you insert "abc" and "def" this way, then the users table will include elements {"def", "abc"} (in this particular order). To retrieve the last inserted element you can use users[1].
If you want to store values in a different order, you need to use table.insert(users, name), which will append elements to the table. To retrieve the last element you can use users[#users].
If you always want to store the added element in the first position in the table, then you can simply use users[1] = name.
Here you index the user table with a string (the name):
elseif users[name] then
You do the same here:
print("Your new user name is: ", users[name])
But you store the name with a numerical index:
table.insert(users, 1, name)
What you want instead of that line is:
users[name] = name
Or this (which would require changing the line that follows):
users[name] = true
The idea is you're only really using the keys, to create a lookup table.

Resources