how do I turn this into a custom excel function? - c#

I have the following C# code, which pulls data from a database & populates cell A1 w/ the data when Excel loads. How do I turn this into a custom function, whereby the field would populate when the user types in the formula (ie '=getMyData("mycustominput")'), rather than when excel loads?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;
using MySql.Data.MySqlClient;
namespace custom_excel
{
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Excel.Worksheet activeWorksheet = ((Excel.Worksheet)Application.ActiveSheet);
Excel.Range firstRow = activeWorksheet.get_Range("A1", missing);
firstRow.EntireRow.Insert(Excel.XlInsertShiftDirection.xlShiftDown, System.Type.Missing);
Excel.Range newFirstRow = activeWorksheet.get_Range("A1", missing);
string connString = "Server=localhost;Port=3306;Database=test;Uid=name;password=password";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = "SELECT field_value FROM customers LIMIT 1";
try
{
conn.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
MySqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
newFirstRow.Value2 = reader["field_value"].ToString();
}
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
}
}

Going out on a limb here, but have you looked at ExcelDNA? It sounds like it might work for what you are trying to do.
There is also this somewhat older article from Eric Carter that might be of use, which uses an automation add-in. It appears you can do it without any 3rd party libraries.

Related

Firebird embedded multiple user support

I'm trying to create an app that communicate with a Firebird 3.0 embedded database.
I need that two or more of my app instances can connect and edit the same database at the same time.
I had create the connection part and it works.
When I start the first instance it connects correctly, but when I try to access to the database with another app it raise this error: Error while trying to open file -Impossible to open the file.
I also had try to connect with different account for example user2 and user1 (manually created with isql) but without results.
I search on google all day but I found nothing.
Any suggestion? Thanks in advance
This is the acutal code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Firebird;
namespace Firebird_multiuser
{
public partial class Form1 : Form
{
//private TextBox console = new TextBox();
Firebird.Firebird conn = new Firebird.Firebird();
public Form1()
{
InitializeComponent();
input_box.Text = #"G:\Coding\oribruniv8\Firebird\Firebird_multiuser\test.fdb";
}
private void button1_Click(object sender, EventArgs e)
{
if (conn.connect(input_box.Text))
console.AppendText("Successfully connect to database\n");
else
{
console.AppendText("Error during connection ...\n");
return;
}
}
}
}
Firebird class
using FirebirdSql.Data.FirebirdClient;
using FirebirdSql.Data.Isql;
namespace Firebird
{
public class Firebird
{
FbConnectionStringBuilder csb = new FbConnectionStringBuilder();
int pageSize = 8192;
bool forcedWrites = true;
bool overwrite = true;
FbConnection conn;
public Firebird()
{
csb.ClientLibrary = **correct path to fbclient.dll**;
csb.UserID = "sysdba";
csb.Password = "masterkey";
csb.ServerType = FbServerType.Embedded;
}
public bool create(string path)
{
csb.Database = path;
FbConnection.CreateDatabase(csb.ToString(), pageSize, forcedWrites, overwrite);
this.conn = new FbConnection(csb.ToString());
this.conn.Open();
return this.connection_check();
}
public bool connect(string path)
{
csb.Database = path;
this.conn = new FbConnection(csb.ToString());
this.conn.Open();
return this.connection_check();
}
public void query(string SQLquery)
{
this.conn.Open();
using (var transaction = this.conn.BeginTransaction())
using (var command = new FbCommand())
{
command.Connection = this.conn;
command.Transaction = transaction;
command.CommandText = SQLquery;
command.ExecuteNonQuery();
transaction.Commit();
}
}
private bool connection_check()
{
if (this.conn.State == ConnectionState.Open)
{
conn.Close();
return true;
}
else
{
return false;
}
}
}
}
If you want two or more apps to connect to the same database, it is time to consider installing Firebird server instead.
That said, if you are using Firebird 3 embedded, it is possible. By default, Firebird 3 embedded will require exclusive access to the database. This can be changed by making sure there is a firebird.conf in the same location as your fbclient.dll used by your application, and setting the ServerMode setting to SuperClassic (or ThreadedShared).
Doing this carries a small risk. If the database is shared, then all processes must use the same lock files. By default that is the case, but if applications have different FIREBIRD_LOCK environment variable settings, this can corrupt a database as each process will think it doesn't have contenders for its locks.

Clearing DropDown List with Invalidate() Outlook Addin C#

Ribbon1.cs using Ribbon Designer (ie, no XML)
I am trying to clear the contents of a Drop Down list before repopulating the list with new data.
I have tried using Invalidate() in several places but I can't get it to work.
The flow of the Addin is as followed:
Copy text to clipboard -> works
Click Search -> works
Get new Data from Database using text from Clipboard -> works
Clear Dropdown -> doesn't work
Populate Drop Down with data. -> Does work but add items to drop down instead of
clearing it first
Thanks in advance
using System;
using System.Collections.Generic;
using System.IO;
using System.Data;
using System.Data.Odbc;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Office = Microsoft.Office.Core;
using Outlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Tools.Ribbon;
namespace MSTEST
{
public partial class Ribbon1 : Office.IRibbonExtensibility
{
private Office.IRibbonUI ribbon;
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
this.ribbon = RibbonUI;
}
private void eventDB(object sender, RibbonControlEventArgs e)
{
RibbonUI.Invalidate();
//this.ribbon.InvalidateControl("resultsDB");
string getTextFromClipboard = Clipboard.GetText();
string queryString = "select distinct file_path as FP, case_id as CS, date_added from documents CONTAINS(documents.file_path, '" + getTextFromClipboard + "') group by case_id,file_path, datE_added order by Date_Added DESC";
using (OdbcConnection odbcConnection = new OdbcConnection("dsn=Needles;UID=dba;PWD=sql;"))
{
OdbcCommand command = new OdbcCommand(queryString, odbcConnection);
try
{
odbcConnection.Open();
OdbcDataReader reader = command.ExecuteReader();
// ribbon.InvalidateControl("resultsDB");
int i = 0;
while (reader.Read())
{
// Being DropDown Populate
RibbonDropDownItem item = this.Factory.CreateRibbonDropDownItem();
item.Label = reader["FP"].ToString();
resultsDB.Items.Add(item);
//MessageBox.Show(reader["CS"].ToString());
// End DropDown Populate
i = i + 1;
}
reader.Close();
odbcConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
public string GetCustomUI(string RibbonID)
{
throw new NotImplementedException();
}
}
}
I have solved this by tinkering around with the Clear() function of the object. example: resultsDB.Items.Clear();

keep having this exception System.Data.OleDb.OleDbException (0x80004005):?

i am developping a really simple program in c# with Visual studio, it consists simply by extracting data from an Excel sheet and transfer it to a database (only one table ), using MySql it worked i just saved the files as CSV and then imported them into my database but i had a big problem which was the encoding UTF8 i have many french characters ans arabic ones that just showed as random characters, so i went back to OleDb but it keeps shong exceptions now i am stuck with this one: System.Data.OleDb.OleDbException (0x80004005)
i ve tried to change running config to x86 but nothing (notice that i am using a windows 8 X64). its a cummon ISAM problem.
please help me .
this is my code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.IO;
using System.Data.OleDb;
namespace testoledb
{
public partial class Form1 : Form
{
DataSet OleDs = new DataSet();
OleDbDataAdapter OleAdapter = new OleDbDataAdapter();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
private void upload_excl_Click(object sender, EventArgs e)
{
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
path = Path.Combine(path, "AGENDA.xlsx");
string OleConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+path+#";Extend Properties=Excel 12.0 Macro;MDR=Yes;ImportMixedTypes=Text;TypeGuessRows=0"; //,HDR=Yes;IMEX=1""";
OleDbConnection OleConn = new OleDbConnection(OleConnectionString);
string OleStrCmd = "select * from [SHeet1$A1:H330]";
OleDbCommand OleCmd = new OleDbCommand(OleStrCmd, OleConn);
try
{
OleConn.Open();
OleDs.Clear();
OleAdapter.SelectCommand = OleCmd;
OleAdapter.Fill(OleDs);
dataGridView1.DataSource = OleDs.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
OleConn.Close();
}
}
}
}

Why does my Outlook becomes slow and sometimes unresponsive after starting an app to clear the clipboard?

I had a requirement to disable Copy Paste and even the print screen key while a website is running. So I wrote a WPF application to keep clearing the clipboard when Open Website link is clicked and stop clearing as soon as Close website button. But the problem is that when I press Open Website button the outlook client becomes very slow and sometimes unresponsive. I know that it has something to do with the clipboard only. Is there a way to disable Outlooks clipboard until the button is pressed.
However the code is not required but is included bleow, or can be downloaded from Dropbox:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Security.Cryptography;
using MySql.Data.MySqlClient;
using System.Threading;
using System.Net.NetworkInformation;
namespace ccb
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
string docNum,qs;
int status = 0;
static string connectionstring = "SERVER=abcd.com;port=3306;DATABASE=abcd_secure;UID=abcd_sec;PASSWORD=abcd_sec";
MySqlConnection conn = new MySqlConnection(connectionstring);
private static Random random = new Random((int)DateTime.Now.Ticks);
public MainWindow()
{
InitializeComponent();
}
private string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
return builder.ToString();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
status = 1;
Thread backgroundThread = new Thread(clear);
backgroundThread.IsBackground = true;
backgroundThread.SetApartmentState(ApartmentState.STA);
backgroundThread.Start();
qs=generaterandomnumber();
insert(qs);
System.Diagnostics.Process.Start("http://abcd/login.php?osid=win&id="+qs);
}
private void clear()
{
while (status == 1)
System.Windows.Clipboard.Clear();
}
//Genrate random number and encrypt it to MD5
private string generaterandomnumber()
{
string Rand1 = RandomString(8);
string Rand2 = RandomString(8);
docNum = Rand1 + "-" + Rand2;
MD5 md5 = new MD5CryptoServiceProvider();
md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(docNum));
//get hash result after compute it
byte[] result = md5.Hash;
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
//change it into 2 hexadecimal digits
//for each byte
strBuilder.Append(result[i].ToString("x2"));
}
return strBuilder.ToString();
}
//Insert the generated value to the database
protected void insert(string q)
{
try
{
conn.Open();
string ins = "insert into mgen_validation_check(md5values) values(#m)";
MySqlCommand cmd = new MySqlCommand(ins, conn);
cmd.Parameters.AddWithValue("#m", q);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start("http://abcd/include/LogoutPage.php");
this.Close();
status = 0;
try
{
conn.Open();
string del = "delete from mgen_validation_check where md5values=#m";
MySqlCommand cmd2 = new MySqlCommand(del, conn);
cmd2.Parameters.AddWithValue("#m", qs);
cmd2.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
private void Window_Closed(object sender, EventArgs e)
{
System.Diagnostics.Process.Start("http://abcd/include/LogoutPage.php");
try
{
conn.Open();
string delconf = "delete from mgen_validation_check where md5values=#m";
MySqlCommand cmd3 = new MySqlCommand(delconf, conn);
cmd3.Parameters.AddWithValue("#m", docNum);
cmd3.ExecuteNonQuery();
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
}
}
The app is working properly except when running outlook becomes very slow. Other ms office apps are working properly.
Any help would be helpful.
Thanks in advance

C# asp.net Disconnecting users terminal service session via loacl intranet

I have written code that uses a .bat file (code: rwvinstat /server:servername) that populates a DataGrid of users logged in to a terminal service session in c#. The .bat lives on the server with the app. files and will run properly if executed manually on the server .Also if i run the app. locally and call the .bat file on the server it works fine.
The problem is when i deploy my web app on the server the DataGrid never populates nor do i get any errors. i have given full permissions to IUSER_MACHINENAME(and various users) and i set the virtual directory permissions to read, run, execute. Ialso have set my web.conf fig to:< "identity impersonate="true" userName="username" password="password"/>
Here is my Source code:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.IO;
public partial class ilsap01_users : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("C:\\listUsersIlsap01.bat");
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process listFiles;
listFiles = System.Diagnostics.Process.Start(psi);
System.IO.StreamReader rawUserData = listFiles.StandardOutput;
listFiles.WaitForExit(20000);
try
{
DataTable table2 = new DataTable();
table2.Columns.Add(new DataColumn("UserName", typeof(string)));
table2.Columns.Add(new DataColumn("SessionId", typeof(string)));
String myString = rawUserData.ReadToEnd();
string exp = #"([\w_]+)"; ;
MatchCollection matches = Regex.Matches(myString, exp, RegexOptions.IgnoreCase);
IEnumerator en = matches.GetEnumerator();
if (en.MoveNext())
{
while (en.MoveNext())
{
Match match = (Match)en.Current;
if (en.Current.ToString() == "rdpwd")
{
if (en.MoveNext())
{
if (en.Current.ToString() == "rdp")
{
en.MoveNext();
en.MoveNext();
en.MoveNext();
Match match_Item = (Match)en.Current;
string item = match_Item.Value;
en.MoveNext();
Match match_Item2 = (Match)en.Current;
string item2 = match_Item2.Value;
DataRow row = table2.NewRow();
row[0] = item.Split()[0];
row[1] = item2.Split()[0];
table2.Rows.Add(row);
}
}
}
}
}
this.displayUsers.DataSource = table2;
this.displayUsers.DataBind();
}
catch (Exception ex)
{
Response.Write(ex);
}
}
protected void dg_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void Button2_Click(object sender, EventArgs e)
{
Response.Redirect("ILSRF01_USERS.ASPX");
}
protected void Button1_Click(object sender, EventArgs e)
{
}
}
Is the executable that the batch file is calling (rwvinstat) in the system path? You might need to call it explicitly - c:\windows\system32\rwvinstat.exe or wherever it is located.
Did you grant the user the application pool is running as the appropriate Remote Desktop Services permissions?
Also, you might find the Cassia library a bit easier to use for your purposes.

Categories

Resources