I have an Excel UDF which takes 2 parameters, I want to utilize Excel built-in Funciton arguments window/dialog, In addition to the standard behavior(ie. you can select cell reference or type in textbox for parameter value), I want to use a dropdownlist for the second parameter, the first parameter has search ability, i.e. when you type in "C", it will pop up a list of availables values starting with "C". I wonder if it is possible to inherit from Excel built-in dialog and how?
If not possible, I have to create custom form to make it work similar to Excel function arguments window. I see A window that behaves both modally and non-modally, maybe that's the way to go? I have not tried yet since I do not quite get what's talked there. thanks
Related
I have an excel addin (*.xla) that contains many complex functions that all take input parameters and return values. I unfortunately cannot create a *.XLL as I don't have access to the *.xla file.
I've managed to use C# to write the excel function into a cell (as a string), calculate the cell, and then retrieve the result back into C#. This method works but it feels very ad hoc and inefficient.
Given the situation described above, is there a better way for calling a custom excel function (that takes parameters) from C#?
How about using the excellent Excel-DNA to build a C# XLL that uses xlfEvaluate to invoke the UDF defined in the .xla? MSDN doc for xlfEvaluate: https://msdn.microsoft.com/en-us/library/office/bb687913.aspx. You can pass in any string that can appear in a worksheet cell. So it shouldn't be too difficult to code some C# to compose the name of the VBA function and some parameters into a string and then pass them to xlfEvaluate.
I've been looking at the microsoft support page Binding for Office automation servers with Visual C# .NET to try to create an Excel Worksheet, populate it with values in a datatable, and save it to the machine.
I have an implementation that uses early-binding and simply loops through the items, but I don't know how you would achieve this with late-binding, and I need to be able to embed the Interop types to make the application version independent in regard to MS Office.
How would I add the rows from a datatable to a new Excel Worksheet using late-binding?
I would recommend writing an interface and abstracting the data population step, and the excel step. That way you can have a system that implements early binding with excel to do things, and then an engine that uses this interface to populate the excel sheet. Step 2 would be to write a second implementation of the interface using Late Binding rather than early binding. Then you just substitute the second implementation for the first in your code when you create the interface.
In the code, you would only create 1 object, the interface itself. When creating it though, you can assign it as any other class/implementation that implements that interface...here's an example from my own code:
ISpreadsheetControl SSInterface;
if (conditionCheck())
SSInterface = new ExcelImplementer();
else
SSInterface = new OpenOfficeImplementer();
I Only ever use the 1 object, SSInterface, when placing data or changing page settings, etc etc...whatever else I implemented...but it can do so in two different manners based on which Class I assigned to the interface at load time.
As for the specifics and details on "how to"...I find the second example in the link you provided to be very helpful indeed. Its all about Type and Invoke. The difficulty will be keeping track of what you are working with at any given time. That is one of the things that will make it harder to work with, and a good reason to extract the early binding implementation first. That way you can see all the method names you will need and their parameter lists when writing the second.
I also want to add this: The very simple and short answer to your question is "Do it exactly the same way you already are" You just change 'how' you are calling the method that is populating the data...and all the rest of the excel interop implementation along with it.
UPDATE
I think this might do what you are looking for, although its messy enough that I would recommend putting it (both operations actually, one can call the other) into its own separate method, somewhere.
//Get a range object that contains the cell.
Parameters = new Object[2];
Parameters[0] = iRow + 1;
Parameters[1] = iCol;
objRange_Late = objSheet_Late.GetType().InvokeMember( "Cells",
BindingFlags.GetProperty, null, objSheet_Late, Parameters );
//Write value in cell
Parameters = new Object[1];
Parameters[0] = row[col.ColumnName];
objRange_Late.GetType().InvokeMember( "Value", BindingFlags.SetProperty,
null, objRange_Late, Parameters );
I have to admit, I don't have an implementation that I can test this on right now, but according to the things I know about it, that should work. If "Cells" doesn't work, I would also the same code with "Range"...I dont actually know if that one takes numerical input or not.
link to Cells property description (msdn)
you might also want to explore that whole system a bit, it can help you find some of the things you might be looking for.
Tested Managed to successfully create and test the above code, it works perfectly.
the application is very large so giving a brief back ground and the problem
when the user logs in, a button is displayed having the text of the function he is allowed to call.
the function he is allowed is mapped in the database table
its made sure that the name of the actual function is same to the ones used in the db.
problem
the name is extracted, and stored as text field of button and also in a string variable.
now how am i supposed to call this function using the string variable which has the name stored in it!
like we type
name-of-function();
but here i dont know the name, the string at run time does so i cant write like
string()!!?
You will need to use reflection to do this. Here is a rough sketch of what you need to do:
// Get the Type on which your method resides:
Type t = typeof(SomeType);
// Get the method
MethodInfo m = t.GetMethod("methodNameFromDb");
// Invoke dynamically
m.Invoke(instance, null);
Depending on your actual needs you will have to modify this a little - lookup the used methods and types on MSDN: MethodInfo, Invoke
Well, no matter what you do, there is going to have to be some kind of mapping done between a database "function" and your "real" function. You can probably use Reflection using your Types and MethodInfo.
However, this sounds like a maintenance nightmare. It also sounds like you are reinventing user roles or the like. I would be very cautious about going down this path - I think it will be much more complex and problematic than you think.
I'm writing a page with several text fields and a drop down. The fields in the drop down affect the value of the text fields.
For example: the drop down options are "a" and "b". The text fields are "name" and "last name". When choosing "a", "name" is filled with "Joe". When choosing "b", "name" is filled with "Bob".
I've written a class which contains the drop down display name and the values for "name" and "last name".
The question: Design-wise, what's the correct solution - having the class change the text fields, or changing the text fields externally and only accessing the class' data?
Thanks.
P.S - I'm using ASP.Net and Javascript, but this is more of a design issue and not language dependent.
Why do you need to populate an input field with the results of a SELECT change? Can't you get your value directly from the SELECT? What do you do if the user changes the result in the input field? The rule I follow is, if the user is allowed to enter any input, use an input text field. If the user is limited to an array of choices, use a SELECT (or possibly a radio button group).
If it is a long list of choices (longer than your example by a couple orders of magnitude), you can include a filter input where the user can type a few letters and pare the options down to a manageable level, but that is the only case I can think of where you'd want to go the other way with it.
Of course, there may be additional information that's on your mind but haven't imparted here. If so, please elaborate.
Since the class contains all three controls, it is correct that it change the text fields, as it is internal behavior to the class. Now if the fields were all separate classes then it would make more sense to manipulate them externally.
If those select fields and text fields combined work as maybe a widget, then it makes much sense to package them as such in a Class like you have already done. Then as Justin said, operations on these controls should be managed by your class, including keeping all fields synchronized.
If there are enough such widgets to care about, then I'd consider separating the data part of it from the views. Maybe create an additional class that represents the data, and pass an object of that data class to the widget. But pragmatism always comes first.
My typical application has a couple of textboxes, checkbuttons, radiobuttons, and so. I always want to load the settings the user used the last time when the program starts, and also want to save the settings as the users clicks "Save settings" or closes the application. When the user attempts to save the settings, I'll have to check each of the controls for input errors (sometimes they have to have a max length, other times only caps, other times other things, there isn't a rule for them all, everytime it'll be different), and only if everything's OK i'll let him save the options. If there is something wrong, no option is saved and my errorcontrol provider will pop up a description of the input type info that should be put in that control.
I've been designing this from scratch for all my projects, but it's being a pain to do it. So I'd thought maybe now was the time to do some library to help me. I thought initially that maybe it'd be a good idea to have all the controls on my form that are going to be part of this save/load process to have an attribute associated with them, something like this
public delegate bool InputIsOkHandler();
public class OptionsAttribute : Attribute {
public Control controlRef;
public InputIsOkHandler IsInputOk;
public string errorMessageToShowOnErrorProvider;
public OptionsAttribute(Control controlRef, InputIsOkHandler inputHandler, string errMessage) {
...
}
}
The main problem here is that when I declare the attribute on a given var:
[Options(...)]
TextBox textBox1 = new TextBox();
I'll get
Error 1 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
So I guess this approach isn't the best one. What would you guys do in this situation? Would you use attributes? Would you use other mechanisms?
Thanks
Do you know that .NET already includes such a system since 2.0? See MSDN, CodeProject and this white paper from WestWind.
The Personalization and User Profiles supported in ASP.NET 2.0 can be a nice way to achieve your goal.
You can check this MSDN article for a overview Personalization in ASP.NET 2.0