Adding Power Queries to Excel using c# - c#

I want to replicate the following code from VBA into c# VSTO:
M_Script = LoadTextFile(qname, wk)
qSource = workbook_path & "\" & qname & ".csv"
Dim qry As WorkbookQuery
Set qry = wk.Queries.Item(qname)
qry.Formula = M_Script
Set qry = wk.Queries.Add(qname, M_Script, qSource)
wk.Connections.Add2 "Query - " & query.Name, _
"Connection to the '" & query.Name & "' query in the workbook.", _
"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & query.Name _
, """" & query.Name & """", 6, True, False
Is there an easy equivalent? I could not find the wk.Queries. I don't want the data to be loaded into the worksheet but create only a connection to the query.
Thanks in advance!

I ended up using the following approach. Though it's not really c# and I hope I will find a better solution at some point.
VSTO Documentation is really sub-standard.
public void addQuery(string m_script_path, string query_name, Excel.Workbook wk)
{
VBComponent newStandardModule;
if(wk.VBProject.VBComponents.Count==0){
newStandardModule = wk.VBProject.VBComponents.Add(Microsoft.Vbe.Interop.vbext_ComponentType.vbext_ct_StdModule);
}
else
{
newStandardModule = wk.VBProject.VBComponents.Item(1);
}
var codeModule = newStandardModule.CodeModule;
// add vba code to module
var lineNum = codeModule.CountOfLines + 1;
var macroName = "addQuery";
var codeText = "Public Sub " + macroName + "()" + "\r\n";
codeText += "M_Script = CreateObject(\"Scripting.FileSystemObject\").OpenTextFile(\""+m_script_path+"\", 1).ReadAll" + "\r\n";
codeText += "ActiveWorkbook.Queries.Add Name:=\""+ query_name+"\", Formula:=M_Script\r\n";
codeText += "ActiveWorkbook.Connections.Add2 _\r\n";
codeText += "\"Query - test\", _\r\n";
codeText += "\"Connection to the '" + query_name + "' query in the workbook.\", _\r\n";
codeText += "\"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" + query_name + ";Extended Properties=\" _\r\n";
codeText += ", \"\"\"" + query_name + "\"\"\", 6, True, False\r\n";
codeText += "End Sub";
codeModule.InsertLines(lineNum, codeText);
var macro = string.Format("{0}.{1}", newStandardModule.Name, macroName);
wk.Application.Run(macro);
codeModule.DeleteLines(lineNum, 9);
}

Related

Loop troguh appointments in outlook stops at first match

I am using Microsoft.Office.Interop.Outlook and I am trying to loop trough all the appointments that match a particular set of conditions:
To reduce the items I limit the search between two knows maximum dates
It has to contain an "ID"
Beside the additional regex that I don't know if it can be fitted in the .Restrict, the foreach loop interrupts at the first entry
DateTime start = DateTime.Now.AddDays(-1);
string filter1 = "[Start] >= '" + start.ToString("g") + "' AND [End] <= '" + DateTime.MaxValue.ToString("g") + "'";
Outlook.Items calendarItems = personalCalendar.Items.Restrict(filter1);
calendarItems.IncludeRecurrences = true;
calendarItems.Sort("[Start]", Type.Missing);
string filter3 = "#SQL=" + "\"" + "urn:schemas:httpmail:subject" + "\"" + " LIKE '%" + AppCode + "%'";
Outlook.Items restrictedItems = calendarItems.Restrict(filter3);
bool error_free = true;
foreach (Outlook.AppointmentItem apptItem in restrictedItems)
{
MessageBox.Show(apptItem.Subject);
try
{
if (Regex.IsMatch(apptItem.Subject, #"^.*##ManaOrdini\d{1,}##.*$"))
{
apptItem.Move(newCalendarFolder);
}
}
catch (System.Exception ex)
{
MessageBox.Show("Si è verificato un errore durante la creazione dell'appuntamento. Errore: " + ex.Message);
error_free = false;
}
}
Can anybody explain me why? Do I have to add a goto method to iterate untill no entry found?
EDIT
The variable restrictedItems contains the following entries:
Subject "Reminder Ordine Numero:1\t##ManaOrdini1#" System.String
Subject "Reminder Ordine Numero:1\t##ManaOrdini##" System.String
Subject "Reminder Ordine Numero:1\t##ManaOrdini1222##" System.String
Subject "Reminder Ordine Numero:1\t##ManaOrdini1##" System.String
EDIT 2
Ended up with this, basically I had to split in two parts:
Clone the results of the filters
Loop and move
DateTime start = DateTime.Now.AddDays( - 2);
string filter1 = "[Start] >= '" + start.ToString("g") + "' AND [End] <= '" + DateTime.MaxValue.ToString("g") + "'";
Outlook.Items calendarItems = personalCalendar.Items.Restrict(filter1);
calendarItems.IncludeRecurrences = true;
calendarItems.Sort("[Start]", Type.Missing);
string filter3 = "#SQL=" + "\"" + "urn:schemas:httpmail:subject" + "\"" + " LIKE '%" + AppCode + "%'";
Outlook.Items restrictedItems = calendarItems.Restrict(filter3);
bool error_free = true;
int c = 0;
List < Outlook.AppointmentItem > listaApp = new List < Outlook.AppointmentItem > ();
foreach(Outlook.AppointmentItem apptItem in restrictedItems) {
if (Regex.IsMatch(apptItem.Subject, #"^.*##ManaOrdini\d{1,}##.*$")) {
listaApp.Add(apptItem);
c++;
}
}
for (int i = 0; i < c; i++) {
try {
listaApp[i].Move(newCalendarFolder);
}
catch(System.Exception ex) {
MessageBox.Show("Si è verificato un errore durante la creazione dell'appuntamento. Errore: " + ex.Message);
error_free = false;
}
}

c# loop with httpclientconnection

I'm trying to run a number of SSRS reports via an SSIS package written in C# using a loop. The problem is that the below code only produces 1 file based on the initial parameters pass through. I think the problem is the ConnectionManager and HttpClientConnection being reused. Is there some other way of doing this?
for (int i = 0; i <= cust.GetUpperBound(0); i++)
{
string varDate = System.DateTime.Now.ToString("dd/MM/yyyy");
string d1ThisMOnth = System.DateTime.Today.AddDays(-(DateTime.Today.Day - 1)).ToString();
var today = DateTime.Today;
var month = new DateTime(today.Year, today.Month, 1);
var first = month.AddMonths(-1);
var last = month.AddDays(-1);
string reportfilename = #"D:\Reports\AllActiveAccounts_" + month.ToString("MMyyyy") + "_" + cust[0, 0] + "." + cust[0, 4];
string url = #"http://" + cust[i, 5] + "/ReportServer?/" + cust[i, 0] + "/Report&rs:Command=Render&location=" + cust[i, 1] + "&clityp=" + cust[i, 2] + "&acctyp=" + cust[i, 3] + "&startdate=" + first.ToString("MM/dd/yyyy") + "&enddate=" + last.ToString("MM/dd/yyyy") + "&rs:Format=" + cust[i, 4] + "&rc:Toolbar=False";
ConnectionManager httpConn = Dts.Connections["ReportServer"];
HttpClientConnection clientConn = new HttpClientConnection(httpConn.AcquireConnection(null));
clientConn.ServerURL = url;
clientConn.DownloadFile(reportfilename, true);
}
It's a bit of a guess, but if I were to. I'd say it's because you're not using your loop counter in your reportfilename parameter. Try changing the filename line to the below.
string reportfilename = #"D:\Reports\AllActiveAccounts_" + month.ToString("MMyyyy") + "_" + cust[i, 0] + "." + cust[i, 4];

Geting out put from Script Html agility pack

i am having problem that this following script generates Email address when page is loaded and i want to parse that email how can i do that?
tr>
<td align='right' class='generalinfo_left' >Email Address:</td>
<td class='generalinfo_right'><script type="text/javascript">
//<![CDATA[
var o3752aaa9bb29d904adeb88838117fd7c = String.fromCharCode(109);var f03de7e643c296e211edddbc3197b33f6 = String.fromCharCode(97);var k7c3bf82468602c0f8dff4950e4b6ff1e = String.fromCharCode(105);var b3eaa633e44451be8df1fa47d75149934 = 'l';var ma2fa16c3a3f532b780aaf0fa5a5b75c6 = 't';var re0c13fc69c03925782867a0540f8c084 = 'o';var j335f1365672123d1fcaf9a83b76f1b7b = String.fromCharCode(58);var f32820e1c54cbc3fa0d418cd1c195eaec = String.fromCharCode(105);var y8c24ea00a7a1edf1c01f794d487697e3 = String.fromCharCode(110);var bcc0ad4f628e703f9ff6e25b87b77ec34 = 'f';var c985c961c7ee85fe6a25d5a66fb421745 = String.fromCharCode(111);var z5ab4e3bdc353d621cea5babcc5dca417 = String.fromCharCode(64);var s4e087167cd0bac466344e72016511172 = String.fromCharCode(97);var re26f6ae180723793af62bc36d5ab2530 = String.fromCharCode(108);var ye1b53d01de118079a38de5e951586731 = 'c';var g9fc5710c9266ce08afbe4da24702dfdd = String.fromCharCode(105);var k5cd5ea1bac40fdbb8b133b7e356809c6 = String.fromCharCode(118);var fcd6e4771e956e270c6897d24ca51c256 = String.fromCharCode(97);var y9d7854a5921fa2be88c8cd72c7e2884e = String.fromCharCode(114);var xa58bea1ecad6fe7d2c736aab1df2df44 = '.';var e4569f6c98804675f7117a84abb0b8d5c = 'c';var o4d2081e2344020922dcb924690c9972e = 'o';var af150185e5eef8ecd8dc1b0a4977c7d55 = String.fromCharCode(109);document.write("<a href='" + o3752aaa9bb29d904adeb88838117fd7c + f03de7e643c296e211edddbc3197b33f6 + k7c3bf82468602c0f8dff4950e4b6ff1e + b3eaa633e44451be8df1fa47d75149934 + ma2fa16c3a3f532b780aaf0fa5a5b75c6 + re0c13fc69c03925782867a0540f8c084 + j335f1365672123d1fcaf9a83b76f1b7b + f32820e1c54cbc3fa0d418cd1c195eaec + y8c24ea00a7a1edf1c01f794d487697e3 + bcc0ad4f628e703f9ff6e25b87b77ec34 + c985c961c7ee85fe6a25d5a66fb421745 + z5ab4e3bdc353d621cea5babcc5dca417 + s4e087167cd0bac466344e72016511172 + re26f6ae180723793af62bc36d5ab2530 + ye1b53d01de118079a38de5e951586731 + g9fc5710c9266ce08afbe4da24702dfdd + k5cd5ea1bac40fdbb8b133b7e356809c6 + fcd6e4771e956e270c6897d24ca51c256 + y9d7854a5921fa2be88c8cd72c7e2884e + xa58bea1ecad6fe7d2c736aab1df2df44 + e4569f6c98804675f7117a84abb0b8d5c + o4d2081e2344020922dcb924690c9972e + af150185e5eef8ecd8dc1b0a4977c7d55 + "'>" + f32820e1c54cbc3fa0d418cd1c195eaec + y8c24ea00a7a1edf1c01f794d487697e3 + bcc0ad4f628e703f9ff6e25b87b77ec34 + c985c961c7ee85fe6a25d5a66fb421745 + z5ab4e3bdc353d621cea5babcc5dca417 + s4e087167cd0bac466344e72016511172 + re26f6ae180723793af62bc36d5ab2530 + ye1b53d01de118079a38de5e951586731 + g9fc5710c9266ce08afbe4da24702dfdd + k5cd5ea1bac40fdbb8b133b7e356809c6 + fcd6e4771e956e270c6897d24ca51c256 + y9d7854a5921fa2be88c8cd72c7e2884e + xa58bea1ecad6fe7d2c736aab1df2df44 + e4569f6c98804675f7117a84abb0b8d5c + o4d2081e2344020922dcb924690c9972e + af150185e5eef8ecd8dc1b0a4977c7d55 + "</a>")
//]]>;
</script></td>
out put is like this
<td class="generalinfo_right">
<script type="text/javascript">
same above script plus following Line
</script>someID#email.com</td>
I wrote my own custom parser that will read the script and parse Email from it.here goes the code
If this code can be optimized or can be written more neatly please let me know
private string ReadEmail(string EmailScript)
{
string EncriptedEmail = "";
string dataPart = "";
dataPart = EmailScript.Substring(0, EmailScript.IndexOf("document.write")).Replace("//<![CDATA[\r", "").Replace("\"", "").Replace("\r\n","");
EncriptedEmail = EmailScript.Replace("\"","");
EncriptedEmail = EncriptedEmail.Substring(EncriptedEmail.IndexOf("'> + "), EncriptedEmail.IndexOf(" + </a>") - EncriptedEmail.IndexOf("'> +")).Replace("'> +", "").Trim();
string[] requiredVariables = EncriptedEmail.Split('+');
List<string> ExtractedDataFromRaw = new List<string>();
string email = "";
foreach (string variable in requiredVariables)
{
string temp = dataPart.Substring(dataPart.IndexOf(variable),dataPart.Length-dataPart.IndexOf(variable)).Replace(" ","");
string tempValueofVariable = temp.Substring(0, temp.IndexOf(";"));
tempValueofVariable = tempValueofVariable.Substring(tempValueofVariable.IndexOf("="), tempValueofVariable.Length - temp.IndexOf("=")).Replace("=","");
if (tempValueofVariable.Contains("String.fromCharCode"))
{
tempValueofVariable = GetCharacterFromASCII(tempValueofVariable.Replace("String.fromCharCode(", "").Replace(")", ""));
}
ExtractedDataFromRaw.Add(tempValueofVariable.Replace("'",""));
email += tempValueofVariable.Replace("'", "");
}
return email;
}
private string GetCharacterFromASCII(string value)
{
int result = 0;
int.TryParse(value, out result);
return char.ConvertFromUtf32(result);
}
That code is building the email address one character at a time from character codepoints and then assembling it later. I suppose this is an attempt to prevent email spam. Depending on what you need to do, it might be easiest to just pull the email address from the link using jQuery or something. $('a[href^=mailto]').attr('href').substring(7) or something ought to do it.

JavaScript Google map marker bug

I'm currently working on an ASP.NET project where I'm using the Google Maps API to show a marker for every company that's registrated in the database.
Everything works just fine, but when I click on a marker the tooltip/dialogbox for the last company in my company list always shows up and not the actualy company mark that's been clicked on.
I can't really get my head around why it is always the last marker that shows up. Here's my updated code:
JavaScript.Text = #"<script type='text/javascript'>
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById('map'));
map.setCenter(new GLatLng(56.4, 10.57983), 9);
map.enableScrollWheelZoom();
}
}
</script> ";
foreach (MemberProfile m in relatedMembers)
{
XmlDocument doc = new XmlDocument();
string address = m.Address;
string zip = m.Zip;
string city = m.City;
string navn = m.Name;
string tlf = m.Phone;
doc.Load("http://maps.googleapis.com/maps/api/geocode/xml?address=" + zip + "+" + city + "+" + address + "+DK&sensor=true&key=ABQIAAAAEaY4JLb9fZFGMlDKuMUlWBRSvyGIkBO7X03pzlT7Z30EPXHR8BS0rXL_ShFm2gc79lZTw2Zak88wng");
XmlNode latNode = doc.SelectSingleNode("GeocodeResponse/result/geometry/location/lat/text()");
XmlNode lonNode = doc.SelectSingleNode("GeocodeResponse/result/geometry/location/lng/text()");
if (latNode != null && lonNode != null)
{
JSAddMarkers.Text += #"<script type='text/javascript'>
var marker = new GMarker(new GLatLng(" + latNode.Value + "," + lonNode.Value + ")); "
+ "var html = '<b>" + navn + "</b><br />" + address + "<br /> " + zip + " " + city + "<br />" + tlf + "'; " + "GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(html); });"
+ "map.addOverlay(marker);"
+ "</script>";
}
If any of you out there can spot the reason why, I would be happy to hear from you! Any help/hint is appreciated :-)
All the best,
Bo
try this
var point =new GLatLng(" + latNode.Value + "," + lonNode.Value + ");
var marker = createMarker(point, address,zip,city,navn);
map.addOverlay(marker);
function createMarker(point, address, zip,city, navn) {
var marker = new GMarker(point, customIcons[type]);
var html = "Address:<b style='padding-left:6px'>" + address+ "</b><br/>zip:<b style='padding-left:6px'>"+ zip+ "</b><br/>city:<b style='padding-left:6px'>"+ city+ "</b>";
GEvent.addListener(marker, 'mouseover', function() {
marker.openInfoWindowHtml(html);
});
GEvent.addListener(marker, "mouseout", function() {
marker.closeInfoWindow();
});
return marker;
}

selenium c#

I wrote a function for extracting attribute "name" of object 'combo box' from browser. But after execution function finishes with an error.
This is the error message:
Selenium.SeleniumException : ERROR: Command execution failure.The error message is: The expression cannot be converted to return the specified type.
This is my function:
public void hladame_combo ()
{
//combo boxes
string nazov_combo;
decimal celkovy_pocet_combo = selenium.GetXpathCount("//select");
int c = 1;
string pomoc = "";
for (c = 1;c<=celkovy_pocet_combo;c++)
{
nazov_combo = selenium.GetAttribute("xpath=//select" + pomoc + "#name");
pomoc = pomoc + " and #name!= '" + nazov_combo + "'";
Console.WriteLine(nazov_combo);
}
Console.WriteLine ("Celkovy pocet combo boxov je = " + celkovy_pocet_combo);
}
problem was in xpath ...
solution is not ideal but helpfull
solution: nazov_combo =
selenium.GetAttribute("xpath=//select[#class != '' " + " " + pomoc + "]#name");

Categories