Is it possible to get the exact progress status when exporting SSRS PDF from AX using x++?
I'm currently struggling to try to find a way to track the exact progress of a report that AX users run in batch, which in the end is saved to a folder as a PDF document.
I'd like to get somehow the progress of this report generation and the PDF exporting so I can update the batch task or even give some feedback about the process to them.
Is kind of tricky, The time it takes will depend on many factors. machine resources, complexity of the report, total records exported by report, etc.
Maybe what you can do is a progress bar that takes into account the total amount of PDF that you are going to export and for each pass update the progress bar ones that are being exported.
Something like that:
static void Stackoverflow(Args _args)
{
#AviFiles
SysOperationProgress progress = new SysOperationProgress();
int i, total;
;
progress.setCaption("Exports PDF");
progress.setAnimation(#AviUpdate);
total = 90000; //Your total of PDF documento to export
progress.setTotal(total);
for (i = 1; i <= total; i++) //Your loop to create PDF
{
//Your code to create PDF in folder
progress.setText(strfmt("PDF generation %1 of %2", i, total));
progress.setCount(i, 1);
//Your code to create PDF in folder END
}
}
Related
I have a google sheet that runs a report on data that is automatically updated. What I would like to do is compare the new inputs with the old inputs to determine if the changes were positive or negative. How would you go about automating a sheet to track these changes?
Changes happen monthly
there would be a score 1-100; 100 being the best
would like to store this data over time for a historical view
Any advice would surely be appreciated
The numbers in each criteria change every month producing a score at the end of the table called Current Score
This score is then pulled into the historical tab as the "Current Score"
What I would like to see happen is that the Current score be saved every month and processed with a percentage change month over month
So I would need a function that stores a copy of the results before they change, processes a new score, and then calculates the difference between the two. Example here is the Dec score (stored values) compared to the most recent score.
Here is a link to the working example
https://docs.google.com/spreadsheets/d/1ImbRhWqGjvIx2CFRKapZ2wmxC9qpSKxxCbHr5tPOBOs/edit#gid=0
Solution
You can automate this process by using Google Apps Script. Open the script editor by clicking on Tools > Script Editor. It is based on JavaScript and allows you to create, access and modify Google Sheets files with a service called Spreadsheet Service.
In addition, you can use Time-driven triggers to run the script automatically once a month. To set it up, click Triggers in the left bar, then Add Trigger and select Time-driven in Select event source. You can now specify the month timer and the exact day and hour you want the script to run. However, I recommend that you do some testing before setting up the trigger to check that you get the desired results. You can test the code by clicking Run in the Editor.
Explanation of the code
There are three functions in the code. The main function is called updateScores and it does what you described in the question. It takes the current score, stores it in a new column and calculates the difference from the last month. Try this function and if you like the result, you can put the trigger in the main function. This way, the trigger calls main which its only responsibility is to call the other two functions. The first is updateScores, which I have already explained, and the second is clearScores, which clears all the values of Reports so you don't have to do it manually and you can start writing the new values for the new month.
I have added some comments so you can understand what each line does.
var lr = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('report').getLastRow()
function updateScores() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Historical')
var currentValues = ss.getRange('B2:B'+lr).getDisplayValues() // get current score
ss.insertColumnsAfter(2,2) // insert two new columns (current score and percent difference)
ss.getRange('D2:D'+lr).setValues(currentValues) // paste stored score
ss.getRange('C2:C'+lr).setFormula('=if(D2=0,"N/A",B2/D2-1)') // apply formula for last stored scores
ss.getRange('E2:E'+lr).setFormula('=if(F2=0,"N/A",D2/F2-1)') // correct formula reference
ss.getRange('E2:E'+lr).copyFormatToRange(ss,3,3,2,lr) // copy format percent
ss.getRange('F2:F'+lr).copyFormatToRange(ss,4,4,2,lr) // copy format scores
var month = new Date().toString().split(' ')[1] // get current month
ss.getRange('D1').setValue(month + ' score') // write current month on last stored scores
var diff = ss.getRange('E1').getDisplayValue() // get diff symbol
ss.getRange('C1').setValue(diff) // write diff
}
function clearScores(){
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('report')
ss.getRange('B2:G'+lr).clear()
}
function main(){
updateScores()
clearScores()
}
Just wondering if there is a better way to display MySql data to users of my app.
Basically I store look-up data then put it in a pop-up window for viewing:
for row in all_reinforcement_data:
r_total = ("Total number of reinforcement entries", mycursor.rowcount)
r_id = ("\n\nId", row[0])
messagebox.showinfo("Reinforcement Data Results", r_total + r_id)
Which doesn't look too polished but gives me what I want:
Is there any other ways of showing the user the data. In some form they could copy and paste from, ideally an excell spreadsheet or something similar.
In a messagebox I don't believe you could do it. You could attempt to do it in a normal window with an entry that you could only copy out of, similarly to this question.
For example, you could do this to show the rows in a simple window:
from tkinter import *
row_info = Tk()
row_info.title("Reinforcement Data Results")
title = Label(text="Total number of reinforcement entries:")
title.pack()
data = Entry(row_info, borderwidth=0, justify='center')
data.insert(END, mycursor.row_count)
data.pack()
data.configure(state="readonly")
close = Button(row_info, text="Ok", command=row_info.destroy)
close.pack()
row_info.mainloop()
I am building an application in Google App Maker that takes in a user-input Excel CSV file with 3 columns and 370,573 rows, so in total 1,111,719 data values. I am trying to efficiently input this data into a MySQL database by sending Batch Requests. However, I am unsure of how to properly optimize this process to minimize the amount of time it takes.
This is how I am currently completing the process:
var file = DriveApp.getFileById(fileID);
var data = Utilities.parseCsv(file.getBlob().getDataAsString());
var stmt = conn.prepareStatement('INSERT INTO report '
+ '(createdDate, accountFullID, lsid) values (?, ?, ?)');
for(var i = 1; i < **data.length**; i++) {
stmt.setString(1, data[i][0]);
stmt.setString(2, data[i][1]);
stmt.setString(3, data[i][2]);
stmt.addBatch();
}
var batch = stmt.executeBatch();
conn.commit();
conn.close();
When testing my code, it took upwards of 3 minutes to complete when I set the for-loop to iterate until variable i was less than 500. When I set the value to a small number like 5, it took several seconds to complete. When I set the value to data.length (as it is currently set to in bold), it never completed and timed out with a deadlock exception. How should I edit my code in order to more efficiently execute batches and reduce the total amount of time it takes when inputting all the data entries from the Excel CSV file, not only a small portion of the spreadsheet?
If this is a one time import, I would use app makers native import function. Create a data model that matches the structure of your cvs document. Then open the csv in a google sheet. make sure the formatting matches the data model and the fields and column names match exactly then use the import function in the top left of the app maker screen. select the google sheet and the data model you created then click import. this should get your data loaded it still make take some time as 1M items is a lot. I see this is 10 months old, so might not have been available back then.
https://developers.google.com/appmaker/models/import-export
I have a report named "Debt Report ". It runs for every month and a pdf is generated at the first of the month by subscription option.
If I am running the report for the month then the report name of the pdf should be "Debt Report for April" and like wise if I run it for may then the name of the pdf should be "Debt Report for May".
How can I do this?
Assuming you are scheduling the report to a file share, you can set the name of the file share to be Debt Report for #timestamp - this will name the file in the format Debt Report for YYYY_MM_DD_HRMINSS .
If you only want the month name (not the entire timestamp) to appear in the filename, you will need to use a Data Driven Subscription.
Another option, although a bit more technical, is to use the rs.exe utility to generate the report. This involves:
creating a script file that generates the report (this is where you can set the filename to your preference)
creating a batch file that calls rs.exe with the script file as a parameter
running the batch file on a schedule e.g. with Windows scheduler or SQL Server Agent
There is an example here of how to do this (to create Excel files but the principle is the same) http://skamie.wordpress.com/2010/08/11/using-rs-exe-to-render-ssrs-reports/
The solution for this problem is "Data Driven Subscription"
http://msdn.microsoft.com/en-us/library/ms169972(v=sql.105).aspx
http://www.kodyaz.com/reporting-services/create-data-driven-subscription-in-sql-server.aspx
the following link helped me alot but the query given in the link creates trouble- cast the datatype of the getdate and it will solve the problem
http://social.msdn.microsoft.com/Forums/en/sqlreportingservices/thread/0f075d9b-52f5-4a92-8570-43bbdaf2b2b1
I have had to do the same thing ( well almost )
I had to generate a weekly report to file and save it as REPORT-Week01.pdf, then REPORT-Week02.pdf etc.
The mechanism I used was to change the parameter column in the Schedule table via a scheduled job. This computed the required file name and simply replaced it. Then when the scheduled job runs, it writes to the file name setup when the schedule was created ( except that was changed at 1 minute past midnight to what I wanted it to be )
I have since implemeted another set of reports that write to a folder, whihc changes each month the the next months folder name ( currently writing all reports to a folder called 202103 ) tonight the job will run and the output folder will change to 202104 and the scheduled jobs will never need changing
I'm a wannabe to .Net and SQL and am working on an SSIS package that is pulling data from flat files and inputting it into a SQL table. The part that I need assistance on is getting the Date Modified of the files and populating a derived column I created in that table with it. I have created the following variables: FileDate of type DateTime, FilePath of String, and SourceFolder of String for the path of the files. I was thinking that the DateModified could be populated in the derived column w/i the DataFlow, using a Script Component? Can someone please advise on if I'm on the right track? I appreciate any help. Thanks.
A Derived Column Transformation can only work with Integration Services Expressions. A script task would allow you to access the .net libraries and you would want to use the method that #wil kindly posted or go with the static methods in System.IO.File
However, I don't believe you would want to do this in a Data Flow Task. SSIS would have to evaluate that code for every row that flows through from the file. On a semi-related note, you cannot write to a variable until the ... event is fired to signal the data flow has completed (I think it's OnPostExecute but don't quote me) so you wouldn't be able to use said variable in a downstream derived column at any rate. You would of course, just modify the data pipeline to inject the file modified date at that point.
What would be preferable and perhaps your intent is to use a Script Task prior to the Data Flow task to assign the value to your FileDate variable. Inside your Data Flow, then use a Derived Column to add the #FileDate variable into the pipeline.
// This code is approximate. It should work but it's only been parsed by my brain
//
// Assumption:
// SourceFolder looks like a path x:\foo\bar
// FilePath looks like a file name blee.txt
// SourceFolder [\] FilePath is a file that the account running the package can access
//
// Assign the last mod date to FileDate variable based on file system datetime
// Original code, minor flaws
// Dts.Variables["FileDate"].Value = File.GetLastWriteTime(System.IO.Path.Combine(Dts.Variables["SourceFolder"].Value,Dts.Variables["FilePath"].Value));
Dts.Variables["FileDate"].Value = System.IO.File.GetLastWriteTime(System.IO.Path.Combine(Dts.Variables["SourceFolder"].Value.ToString(), Dts.Variables["FilePath"].Value.ToString()));
Edit
I believe something is amiss with either your code or your variables. Do your values approximately line up with mine for FilePath and SourceFolder? Variables are case sensitive but I don't believe that to be your issue given the error you report.
This is the full script task and you can see by the screenshot below, the design-time value for FileDate is 2011-10-05 09:06 The run-time value (locals) is 2011-09-23 09:26:59 which is the last mod date for the c:\tmp\witadmin.txt file
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
namespace ST_f74347eb0ac14a048e9ba69c1b1e7513.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
public void Main()
{
Dts.Variables["FileDate"].Value = System.IO.File.GetLastWriteTime(System.IO.Path.Combine(Dts.Variables["SourceFolder"].Value.ToString(), Dts.Variables["FilePath"].Value.ToString()));
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
C:\tmp>dir \tmp\witadmin.txt
Volume in drive C is Local Disk
Volume Serial Number is 3F21-8G22
Directory of C:\tmp
09/23/2011 09:26 AM 670,303 witadmin.txt