Script task to check if file exists then email - ssis

I've got a simple SSIS package that I want to include a section that determines if the file existed in the folder or not and email out either a fail or pass email. I've tried to use a script task after the main for loop section,and use precedence constraints to email either the file was there or not depending on success or failure. Every time I run it the script it picks up a success flag (File is present) from somewhere, when the file isn't there.
I put a message box output in the script code to show if the file exists variable was set to False or True, and it came up False, as well as on the mail send it shows false for variable value, but is sending a success email.
Iv'e got the following variables in my script task, the FileExist is a boolean variable set at package level to default false. In my script code I am checking if the xlFileName is existing and then setting a flag to print out Y or N
The code in the script is as follows:
Public Sub Main()
Dim fileExists As String
fileExists = CType(File.Exists(Dts.Variables("User::xlFileName").Value.ToString()), String)
If fileExists = "False" Then
MessageBox.Show("N")
Else
MessageBox.Show("Y")
End If
End Sub
Do I need to set the ScriptResult in the code to success/Failure, depending on outcome?
Dts.TaskResult = ScriptResults.Success
I tried this earlier and the script task just failed.
In the precedence constraints (Set to Evaluate Operation: Expression) I also had the following but removed them as they were not making any difference, but tested ok.
#[User::FileExists]="False" - For No File
#[User::FileExists]="True" - For File Present
I'm not a regular user of ssis, nor have I used script tasks as far back as I can remember, so be kind!
Thanks
Andrew
Edit: Precedent Constraint settings images below. I've now got these set to check the variable for true/false depending on if file is present or not:
Changed the variable to populate with True as a Boolean rather than a string value, and set taskresult to Success/Failure.
Public Sub Main()
Dim fileExists As Boolean
fileExists = CType(File.Exists(Dts.Variables("User::xlFileName").Value.ToString()), Boolean)
If fileExists = False Then
Dts.TaskResult = ScriptResults.Failure
Dts.Variables("User::FileExists").Value = False
Else
Dts.TaskResult = ScriptResults.Success
Dts.Variables("User::FileExists").Value = True
End If
End Sub
When I run the script and the file is not available the script task fails but sends the mail as if success:

Related

parsing value to a variable when clicking a checkmark, access, VBA code

What is the VBA code to parse a value into a different field in the db when a checkbox is clicked?
Example code (that doesn't work):
Private Sub Step_1_Click()
If Step_1.Value = True Then
Step1_score.Value = 10
End if
End Sub
I removed the "value" and got no code errors but the 10 is not showing up in the Step1_score variable in the db. Any advise on the VBA code to parse a value from a checkmark? Thanks!
You probably want to use the _AfterUpdate event to make sure the value of Step_1 gets changed before the event fires:
Private Sub Step_1_AfterUpdate()
If Step_1.Value = True Then
Step1_score.Value = 10
End if
End Sub

Error trying to Upload image using srrs using rs.exe -"The required field Property is missing from the input structure"

Scenario : Upload image using srrs using rs.exe (using code not GUI)
Environment : Sql server 2012, rs.exe , vb.script
'Utility to Publish the Png file ( snippet)
'Sample inputs PublishImageFile("myimagefilename.png", "image/png")
Public Sub PublishImageFile(ByVal imageName As String,ByVal resourceMIME As String)
Try
Dim stream As FileStream = File.OpenRead(filePath + "\" + imageName)
definition = New [Byte](stream.Length - 1) {}
stream.Read(definition, 0, CInt(stream.Length))
stream.Close()
Catch e As IOException
Console.WriteLine(e.Message)
End Try
imageName = imageName.tostring.replace(".png", "")
Console.WriteLine("Attempting to Deploy Resource Name {0}", imageName.tostring)
Dim item As CatalogItem
Dim mimeProperty As New Microsoft.SqlServer.ReportingServices2010.Property
mimeProperty.Name = "MimeType"
mimeProperty.Value = resourceMIME
Dim properties(1) As Microsoft.SqlServer.ReportingServices2010.Property
properties(0) = mimeProperty
Try
item = rs.CreateCatalogItem("Resource", imageName, ReportFolder, True,
definition, properties, warnings) 'Error line
'More code below removed for brevity
Error I receive in the last line above is
The required field Property is missing from the input structure. ---> Microsoft.ReportingServices.Diagnostics.Utilities.MissingElementException: The required field Property is missing from the input structure.
What are the required parameters required in the properties object to fix the issue.
I did not find the same in CreateCatalogitem method in MSDN
https://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.createcatalogitem(v=sql.120).aspx
Nor in the Catalog item description in MSDN
https://msdn.microsoft.com/en-us/library/reportservice2010.catalogitem.aspx
From the error message and investigation it appears ( my assumption) like a required field named 'Property' could missing from the properties array. But what would be its value?
Please share your suggestions & solutions or may be even an code alternative to rs.exe to automate deploy images to ssrs using script.
I found the answer. I just added an additional property named property and name as filename just before the CreateCatalogItem method and it worked!
Dim propertyItem As New Microsoft.SqlServer.ReportingServices2010.Property
propertyItem.Name = "Property"
propertyItem.Value = imageName
properties(1) = propertyItem

SSIS Convert Blank or other values to Zeros

After applying the unpivot procedure, I have an Amount column that has blanks and other characters ( like "-"). I would like to convert those non-numberic values to zero. I use replace procedure but it only converts one at the time.
Also, I tried to use the following script
/**
Public Overrides Sub Input()_ProcessInputRows(ByVal Row As Input()Buffer)
If Row.ColumnName_IsNull = False Or Row.ColumnName = "" Then
Dim pattern As String = String.Empty
Dim r As Regex = Nothing
pattern = "[^0-9]"
r = New Regex(pattern, RegexOptions.Compiled)
Row.ColumnName = Regex.Replace(Row.ColumnName, pattern, "")
End If
End Sub
**/
but i'm getting error.I don't much about script so maybe I placed in the wrong place. The bottom line is that I need to convert those non-numberic values.
Thank you in advance for your help.
I generally look at regular expressions as a great way to introduce another problem into an existing one.
What I did to simulate your problem was to write a select statement that added 5 rows. 2 with valid numbers, the rest were an empty string, string with spaces and one with a hyphen.
I then wired it up to a Script Component and set the column as read/write
The script I used is as follows. I verified there was a value there and if so, I attempted to convert the value to an integer. If that failed, then I assigned it zero. VB is not my strong suit so if this could have been done more elegantly, please edit my script.
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
' Ensure we have data to work with
If Not Row.ColumnName_IsNull Then
' Test whether it's a number or not
' TryCast doesn't work with value types so I'm going the lazy route
Try
' Cast to an integer and then back to string because
' my vb is weak
Row.ColumnName = CStr(CType(Row.ColumnName, Integer))
Catch ex As Exception
Row.ColumnName = 0
End Try
End If
End Sub

SSIS flat file loading by checking conditions

I've 10 flat files(.dat format) in a folder which need to be uploaded into database everyday at a scheduled time.
All files related information are present in a database like File name, file path, table name, column names and delimiter.
We need to check each file exists or not, if not, need to log an entry, "File Not Found".
If the file exists, it needs to check for a trailer record(the last record in the file which says, Count=00001000, It has to be the count of number of records in that particular file).
If the trailer record not exists, then need to log an entry "No trailer record found".If the trailer record says zero count, then a log entry has to be made "Zero count" and also, if the counts of the file are not matching a log entry is needed, "Count mismatch".
If all the conditions are satisfied then data need to be loaded into database for each of the file.
Please suggest your ideas to implement the above scenario. Thanks!!!
Following solution may help you to resolve the issue.
Use the For each loop container with "Item" enumerator. Since you have 10 files and if something missing you need raise then you should use this. File enumerator just iterate through the files, not raises any error.
Following are Steps.
Create following SSIS package with variables.
FileFullPath
IsValidated
For each loop enumerator should be configured as following screenshots.
Configuartion in collection:
configuration in Variable section
Inside the container have a script task. you have to mention the FileFullPath as readonly variable and IsValidate as read and write like the following screen.
Click Edit script and insert the following code.
public void Main()
{
Dts.Variables["IsValidated"].Value = true;
string fileFullPath = Dts.Variables["FileFullPath"].Value.ToString();
if (!File.Exists(fileFullPath))
{
var msg = String.Format("File is not available in location : {0}", fileFullPath);
Dts.Events.FireError(0, "Dat file loading", msg, string.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
//Read last line
String lstLine = File.ReadLines(fileFullPath).Last();
int totalCount = 0;
bool talierExists = int.TryParse(lstLine, out totalCount);
if (!talierExists)
{
var msg = String.Format("No tailer row found and last line is : {0}", lstLine);
Dts.Events.FireError(0, "Dat file loading", msg, string.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
//Total count
int fullCount = File.ReadLines(fileFullPath).Count();
if (fullCount != totalCount)
{
var msg = String.Format("No of count is not matching, tailer count = {0} and full count={1}");
Dts.Events.FireError(0, "Dat file loading", msg, string.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
Dts.Variables["IsValidated"].Value = true;
Dts.TaskResult = (int)ScriptResults.Success;
}
After that have your Data flow. Connect the script task with your data flow and right click on the connector and go to edit and configure as follows.
Your SSIS package will looks like follows.
Hope this helps!

how to check end of file in a csv file before processing it in ssis

I have created an SSIS package which processes .CSV files using a ForEachLoop container.
All the csv files contains "END OF FILE" in the last row.
Only those CSV files will be processed if it contains "END OF FILE" in the last row.
How can it be done. Please help.
Thanks in advance.
Create a variable check
Name DataType Value
check int 0
Let's say you have a package design like the one below
Script task is to check the file which has End of File at the last row
In the Script task add the variable check in ReadWriteVariable section and the output variable from ForEach container (suppose the variable name is LoopFiles) in ReadOnlyVariables
In the script task add the following code to read the file .There are several ways you can read the files here and here
public void Main()
{
int counter = 0;
string loop= Dts.Variables["User::LoopFiles"].Value.ToString();
string line;
using (StreamReader files = new StreamReader(file))
{
while((line = files.ReadLine()) != null)
{
if (line.ToLower() == "End Of File".ToLower())
{
Dts.Variables["User::check"].Value = 1;
}
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
Double Click the green arrow connection script task and Data Flow Task .A precedence dialog box will open and enter the expression as below
There are a number of ways that this could be done. One way would be:
Create the following variables:
EOF_Found Boolean
Row_Count Integer
Bring the data into a dataflow using the Flat File Source
Use a row count component to add the number of rows to Row_Count, to identify the last row later
Use a script component to loop through the rows, adding 1 to a counter for each row
When your counter equals the value in Row_Count (i.e. you are looking at the last row) check the value in the column that you expect "END OF FILE" to appear (depends on how you set up the flat file connection manager). if it equals "END OF FILE", change the value of EOF_Found to True
After the script component, add a derived column referencing the value in EOF_Found
Use a conditional split, checking the value of the derived column and only process if True
This solution avoids reading the entire file line by line. I have merged Praveen's code here for sake of completeness.
public void Main()
{
string line = ReadLastLine(#"c:\temp\EOF.cs");
if (line.ToUpper() == "END OF FILE")
{
Dts.Variables["User::check"].Value = 1;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
public static string ReadLastLine(string path)
{
StreamReader stream = new StreamReader(path);
string str = stream.ReadToEnd();
int i = str.LastIndexOf('\n');
string lastLine = str.Substring(i + 1);
return lastLine;
}