Re: Localization of functions descriptions

896 views
Skip to first unread message

Govert van Drimmelen

unread,
Dec 6, 2012, 8:13:03 AM12/6/12
to Excel-DNA
Hi Leonardo,

There's no easy way to do it now, but I think it's a great suggestion
for a future version. Maybe we could have a way for the attributes to
pull the information out of a resource file or something.

What I'd suggest for now is to have multiple add-ins, where each just
has a simple wrapper of [ExcelFunction] marked functions, calling to a
shared library. Doing this with the (limited) support for dynamic
registration is probably not worth it.

Regards,
Govert


On Dec 6, 2:46 pm, Leonardo Gabriel Salmaso
<leonardo.salm...@gmail.com> wrote:
> Hi I'm need to develop a Excel addin in different languages, and I have a
> question about the help descriptions of the functions. Is it possible
> localise this descriptions depending of the office language??
>
> Example:
>
> [ExcelFunction(Description = "Get Person Name"....)  ---- English
>
> [ExcelFunction(Description = "Obtener nombre de la persona"....)  ----
> Spanish
>
> Cheers,

Govert van Drimmelen

unread,
Dec 6, 2012, 1:38:17 PM12/6/12
to Excel-DNA
Hi,

We're pretty much done with version 0.30.
So I'm happy to try to work on this as a start to the next version.

Perhaps the two of you could discuss a bit about how you'd like it to
work.
In particular:

1. Where should the localized strings be stored and managed?
2. How should the ExcelFunction attribute be changed to accommodate
localized strings?
3. What would the code look like that finds the localized strings from
the attribute information? How do we get the right UI language using
Application.International or Application.LanguageSettings?
4. Do we also need to deal with localization of ribbon resources? Is
there anything built in to the Office ribbon libraries for that? How
does ribbon localization work on VSTO? (Maybe just loading the right
xml string according to the language is good enough?)

This needs to be done in a way that is compatible with the current
version.

-Govert


On Dec 6, 3:40 pm, Fernando Alonso <alonso.fernando.mo...@gmail.com>
wrote:
> Hi Govert,
> I have the same problem as Leonardo, I have my information helps locate and
> manage different versions is not viable for me as I have to locate my addin
> in 7 languages. there any way to make dynamic descriptions?
>
> kind regards,
>
> Fer.
>
> El jueves, 6 de diciembre de 2012 10:13:03 UTC-3, Govert van Drimmelen
> escribió:

Govert van Drimmelen

unread,
Jan 22, 2013, 9:59:57 AM1/22/13
to Excel-DNA
Hi Fernando,

I think the HelpTopic should already allow relative paths. If the
HelpTopic is not a url starting with http or https, and is not a
rooted path, like C:\... or \\Server\Share\...., then Excel-DNA will
prepend the HelpTopic with the location of the .xll file.
If you don't find that it works this way, let me know so that we can
test further.

Your suggestion for how the function descriptions might be localised
with the ExcelFunction attribute won't work - C# required that the
parameters passed to the attribute constructor be known at compile-
time.
Designing some way to do the localisation is a good idea but will need
some more thought....

Regards,
Govert


On Jan 21, 2:33 pm, Fernando Alonso <alonso.fernando.mo...@gmail.com>
wrote:
> It would be great if the "ExcelFunction Description" support variables with
> non-constant value, such as:
>
> Description1 var = String.Format ({0}, Description1.localization)
>
> [ExcelFunction (
> Description = Description1]
>
> Same for
>
> [ExcelFunction (
> [ExcelArgument (Description =
>
> It would also be good for the field "ExcelFunction HelpTopic" supports more
> complex routes such as:
>
> [ExcelFunction (HelpTopic = "/ Resources / xxxx.chm! 150"
>
> thank you.
>
> El jueves, 6 de diciembre de 2012 15:38:17 UTC-3, Govert van Drimmelen

Govert van Drimmelen

unread,
Feb 16, 2013, 9:23:18 AM2/16/13
to Excel-DNA
Hi Gin,

As a start, maybe you'd like to have a go at providing the following:

1. the attribute syntax (in a backward-compatible way)
2. the code that decides what language to load
3. the code to load the string according to the attribute info

Doing the part that integrates it into the Excel-DNA registration is
not hard, once the basic mechanism is figured out.

-Govert



On Feb 16, 12:42 am, ginn...@gmail.com wrote:
> Hi Govert,
>
> I also would like to have this feature ASAP. Ideally, I like to just
> putting the key of the resources in the description attribute of the
> function and DNA uses it to get the string from the resources, I think this
> is how Microsoft does it internally. The problem is how DNA get at the
> resources. Would it be possible to use another attribute to specify the
> fully qualified name of the resource class and somehow DNA is able to load
> the resources and do the look up?
>
> Thanks for your great effort of creating Excel-DNA.
>
> Gin

Govert van Drimmelen

unread,
Feb 21, 2013, 4:55:35 AM2/21/13
to Excel-DNA
Hi Gin,

That looks promising.
I'm not sure if your resources string refers to a type or an assembly?
How do we make the resource assemblies work with the packing? How does
the ResourceManager do the probing for different langauges?
I wonder if the culture when the Excel-DNA add-in is loaded in Excel
is all fine.

Would you be able to try it?
(Maybe make an add-in with a function that returns a localised string,
with two parameters, your "Resources" string and the Description
string.)

-Govert


On Feb 19, 11:37 pm, ginn...@gmail.com wrote:
> Hi Govert,
>
> For the attribute syntax, we can add a new attribute 'Resources' to specify
> the resource name. If it is specified, then the description attribute is
> the key of the resource string in the resources. For example,
>
> [ExcelFunction(Name = "TOTAL", Description = "TotalDescription", Resources = "MyExcelAddIn.Properties.Resources", IsThreadSafe = false, IsVolatile = true)]
>
> Here "MyExcelAddIn.Properties.Resources" contains a resource entry with
> "TotalDescription" as the key of the resource string. The resource file
> need to be located in the same assembly of the function, you will see why
> later.
> If the Resources attribute is not specified, the description attribute is
> treated as before, i.e. it is the description string. Therefore, it is
> backward compatible.
>
> For 2&3, we should be able to use ResourceManager to retrieve the culture
> sensitive string from the resources. In class XlMethodInfo, modify
> SetAttributeInfo() to also take the assembly object of the function. The
> call becomes
> SetAttributeInfo(targetMethod.GetCustomAttributes(false),
> targetMethod.Module.Assembly);
>
> In SetAttributeInfo(), add code to retrieve the resource string if
> necessary:
>
>     if (TypeHelper.TypeHasAncestorWithFullName(attribType, "ExcelDna.Integration.ExcelFunctionAttribute"))
>     {
>         string name = (string) attribType.GetField("Name").GetValue(attrib);
>         string description = (string) attribType.GetField("Description").GetValue(attrib);
>         // new code
>         string resources = (attribType.GetField("Resources") != null) ? attribType.GetField("Resources").GetValue(attrib) : null;
>         if (resources != null)
>         {
>             description = new ResourceManager(resources, assembly).GetString(description);
>         }
>         ...
>
> This is the basic idea. I haven't try it out. Do you think it will work?
>
> Gin

Naju Mancheril

unread,
Feb 21, 2013, 2:18:33 PM2/21/13
to exce...@googlegroups.com

Hi Govert,

What do you think of a more general solution? I can imagine that some places want site-specific names and descriptions.

We can support this by giving the user the ability to specify a type which ExcelDna will instantiate and call into:


Attempt 1: Add an interface to provide some (all?) property values. Let the user specify the implementing type.

  public interface IExcelFunctionInfo {
    string Name { get; }
    string Description { get; }
...
  }

    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    public class ExcelFunctionAttribute : Attribute
    {
...
      public Type InfoType;
...

}


Attempt 2: Add an attribute factory type. Let the user specify the implementing type.

  public interface IExcelFunctionAttributeFactory {
    ExcelFunctionAttribute Create();
  }

    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    public class ExcelFunctionAttribute : Attribute
    {
...
      public Type FactoryType=null;
...

This latter approach keeps the API surface smaller since you don't need to track function properties on both the attribute and the interface.

You should only need to create one instance of each specified type. You can stash it in a Dictionary<Type,IWhatever> and reuse it.

These types can also be used for other things. For example they can return false/null for some property to indicate that a given function should not be registered at all. Developers can then control at runtime whether a given user has access to a given function.


Naju

Naju Mancheril

unread,
Feb 21, 2013, 2:27:49 PM2/21/13
to exce...@googlegroups.com
Attempt 3: Provide the IWhatever class with some context

public interface IExcelFunctionAttributeFactory {
  ExcelFunctionAttribute Create(ExcelFunctionAttribute attribute, MethodInfo methodInf);
}

In Attempt 2, you needed a distinct factory type for each function (otherwise, the name could not be different!). This is better since the type is acting as a filter on top of the compile-time information that the code already provides. The MethodInfo (which points to the implementing function) provides the code with even more context.

Govert van Drimmelen

unread,
Mar 1, 2013, 5:36:13 PM3/1/13
to Excel-DNA
Hi Gin, Naju,

I like this because it is a conservative extension to the API (I feel
quite cautious about adding extra types to the public interface this
week). It allows you to implement the whole localization story
yourself, and supports other scenarios like user-based registration.

I'll see what I can do...

-Govert


On Mar 1, 9:45 pm, ginn...@gmail.com wrote:
> Hi ngm,
>
> This is good idea, definitely more flexible. But why not just provide two
> utility methods for the addin to call? For example,
>
> public static void RegisterMethod(MethodInfo method, ExcelFunctionAttribute
> functionAttribute, IEnumerable<ExcelArgumentAttribute> argumentAttributes)
> public static void UnregisterMethod(MehtodInfo m)
>
> With these methods, the addin can make all kind of runtime decisions before
> registering the methods and they can be called anytime at will instead of
> just during the load time. I include a list argument attributes because
> argument also has description and the number of arguments can be varied
> during the runtime, e.g. TOTAL(a, b, ...). This also has the side effect of
> making the attribute declaration optional for the UDF.
>
> Gin
>
>
>
>
>
>
>
> On Thursday, February 21, 2013 2:27:49 PM UTC-5, ngm wrote:
>
> > *Attempt 3: Provide the IWhatever class with some context*

Naju Mancheril

unread,
Mar 1, 2013, 6:17:17 PM3/1/13
to gin...@gmail.com, exce...@googlegroups.com
Very cool! We'll probably need one more register method for ExcelCommandAttribute, but that should be fairly straightforward.

Govert van Drimmelen

unread,
Mar 4, 2013, 4:37:20 PM3/4/13
to Excel-DNA
Hi Gin,

OK - I've checked in a first attempt at this. The ExcelIntegration
class now has:

public static void RegisterMethods(List<MethodInfo> methods,
List<object>
methodAttributes,
List<List<object>>
argumentAttributes)

There is an example in Distribution\Samples\DynamicMethodSample.dna
that now calls this.

I have not tested it much, so I'd advise some caution with this
version.

Of course this does not directly address the localization issue yet,
but you should now be able to do so inside your add-in. If you do make
some implementation of localized functions, please post back your code
for others to look at :-)

Regards,
Govert



On Mar 4, 6:25 pm, ginn...@gmail.com wrote:
> Awesome. Thank you.
>
> Gin

Govert van Drimmelen

unread,
Mar 19, 2013, 1:39:17 PM3/19/13
to Excel-DNA
Hi Gin,

I'm glad you've been able to make it work.
Have you been able to use it to do localization of the function
descriptions? Would you be able to post some code that shows how you
did it?

Regarding the issue you mention:
1. I'm surprised that you had problems with the version of the .xll in
the Distribution directory. Although it was built with VS 2012, that
should make no difference to how you use it. It seems to work on my
side.
Can you remember what the exception was that you got? Perhaps you had
a problem of mismatched .xll and ExcelDna.Integration.dll versions?

For rebuilding Excel-DNA from source under Excel 2010, you need to
update the vcproj file, as you mention. I'll try to set it back in the
next check-in - it should make no difference to the compiled library.

2. You can call RegisterMethods from any macro context (though not
from a worksheet function). You won't be able to call it directly from
a ribbon handler - your Application.Run call or calling
ExcelAsyncUtil.QueueAsMacro would work.


Regarding your suggestions:
1. Registering a partial method based on the number of ExcelArgument
attributes would be inconsistent with the compiled code, so I'm not
sure it's the right way to go. In any event, I'd have to implement the
partial methods by synthesizing the partial method with a
DynamicMethod that wraps a call to the real method, with appropriate
defaults (presumably depending on the extra parameter types). This
would not be much easier to put into the Excel-DNA code than your own
library, so I suggest you give it a try on your side.

2. Properly unregistering is a problem given the current Excel-DNA
implementation - the design basically matches that of .NET, where an
AppDomain (which matches an Excel-DNA add-in) is the unit of loading
and unloading code. So each call to RegisterMethods has significant
overhead - behind the scenes a new assembly is compiled and loaded.
These assemblies can never be unloaded from the AppDomain. Changing
this would take some thinking and some work...

I post some code below that will remove the function's name from
Excel, but the memory and internal Excel-DNA structures are not
cleaned up.

The only reliable and safe way to add and remove functions at runtime
is to load and unload a separate .xll.

The unregister code goes like this:

private static void RemoveFunctionName(string name)
{
// get the path to the XLL
var xllName = XlCall.Excel(XlCall.xlGetName);

// get the registered ID for this function and unregister
var regId = XlCall.Excel(XlCall.xlfEvaluate, name);
XlCall.Excel(XlCall.xlfSetName, name);
XlCall.Excel(XlCall.xlfUnregister, regId);

// reregister the function as hidden and then unregister (clears
the function wizard)
var reregId = XlCall.Excel(XlCall.xlfRegister, xllName,
"xlAutoRemove",
"I", name, ExcelMissing.Value, 2);
XlCall.Excel(XlCall.xlfSetName, name);
XlCall.Excel(XlCall.xlfUnregister, reregId);
}

Thank you very much for the feedback :-)

Regards,
Govert



On Mar 19, 6:36 pm, ginn...@gmail.com wrote:
> Hi Govert,
>
> We have finally tried the new method and it worked well. Thank you.
>
> We encountered a couple of problems though before we can make it work.
>
> 1. We were not able to use your xll from the Distribution folder. We got
> exception when calling the new method. We found out that your xll is
> probably built with VS2012 but we are still using VS2010. In order to fix
> it, we need to change the Platform Toolset configuration property of
> ExcelDna project from v110 to v100 and rebuild with VS2010.
>
> 2. We found that RegisterMethods() did not do anything if it is not called
> within AutoOpen(). We solved the problem by putting RegisterMethods() in an
> [ExcelCommand] method and invoking the command method with
> ExcelDnaUtil.Application.Run().
>
> I would like to ask for two enhancements:
>
> 1. Right now, even I set up the parameter list with fewer parameters than
> the declaration of the UDF, I still get some of the original parameters
> appended. Can we change it to if an non-empty parameter list is supplied,
> then it just register the parameter list and not append the original
> parameters from the declaration of the UDF. Use the original parameters
> only if a null or empty parameter list is supplied. This way, I can
> dynamically change both the names and the number of the parameters in
> run-time.
>
> 2. I need to register the methods multiple times with different parameters
> according to the context during the run-time. I think the current
> implementation keep the old registrations around in an internal list. The
> list will grow and grow after each round of registrations. Would you be
> able to provide a unregister method or even better if you can remove the
> old registration from the internal list automatically by matching the name
> of the UDF. I am not sure you need to actually do an Excel unregister or
> not, it seems Excel just replace the method if the method is registered
> again.
>
> Many thanks,
> Gin
>
>

Dr DB Karron

unread,
May 21, 2013, 11:38:08 AM5/21/13
to exce...@googlegroups.com
I just noticed this thread and want to weigh in:

I need multiple languages: Chinese (Simplified) and Hebrew.

I have gotten this to work in Visual Studio with VSTO;
Long paths with spaces continue to be a problem; it breaks VS12.
Search paths in the packer are a problem;
dynamic updating so you don't have to reboot excel and use .NET daemon
should be ready soon; this enables you to compile between keystrokes or during
pauses continuously. 




______________________________________
"Dr D B Karron" <drdbk...@gmail.com>
<kar...@casi.net> skype: drdbkarron
+1 (516) 515-1474 (will find me)
+1 (917) 674-0828 (voice and cell texting, sms)



On Tue, May 21, 2013 at 10:02 AM, Fernando Dias <fernand...@gmail.com> wrote:
Hi,

great work, I am trying to do the same thing, but I don´t know how I can do.
Can you please give me some tips?
After I registe my method, how can I use it?
When I registe my method I can´t registe my funclist and my arglist,
ExcelIntegration.RegisterMethods(methodsList, funcList, argList);
This code give me error: No overload for method 'RegisterMethods' takes 3 arguments
Can you please help me?

thanks,
Dias


Terça-feira, 9 de Abril de 2013 21:22:22 UTC+1, gin...@gmail.com escreveu:
Hi Govert,

Sorry for the late response. I was switched to work on something urgent for the last few weeks.

Yes, we are able to use it to do localization of the function. We just simply get the description from the resource file in the standard way and set up the function attribute fields before registering the method. Code example:

        ExcelFunctionAttribute functionAttribute = new ExcelFunctionAttribute();
        List<ExcelFunctionAttribute> funcList = new List<ExcelFunctionAttribute>();

        functionAttribute.Name = "Total";
        functionAttribute.Description = Properties.Resources.TotalDescription;    // get the localized description
        funcList.Add(functionAttribute);
        ...
        ExcelIntegration.RegisterMethods(methodsList, funcList, argList);    // register the methods

For the problem of the distributed xll, the exception is something like MSVCR110D.dll is missing. This is the VS2012 run-time dll. The problem occurs when I try to debug the add-in with VS2010. VS2012 installation replaces .Net 4 with .Net 4.5 and that causes some of existing .Net 4 applications to break. That's why we haven't upgraded to VS2012.

Thanks for the suggestion of using DynamicMethod, I'll give it a try later.

For the unregistering of the method. I don't really concern on unregistering the method from Excel, I can just set the hide attribute if I don't want the method to appear, and it seems Excel would just replace the method if the method with the same name is registered again. I only worry about the internal memory usage of Excel-DNA. For my application, I need to re-register the same methods whenever the arguments changed, the DNA internal method list will keep on growing because each one is allocated with a new id/slot. Instead of providing a unregister method, may be a better solution is to change the registering code to reuse the same id/slot if it detects the method with the same name is already exist in the list.

Thanks,
Gin

--
You received this message because you are subscribed to the Google Groups "Excel-DNA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to exceldna+u...@googlegroups.com.
To post to this group, send email to exce...@googlegroups.com.
Visit this group at http://groups.google.com/group/exceldna?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

John S

unread,
Mar 14, 2017, 6:59:57 AM3/14/17
to Excel-DNA
Hi Govert,

I need to implement multi language for description of ExcelFunction and ExcelArgument.
I'm using ExcelDna-0.33.9.
So do you know what approach to implement this in ver 0.33.9?

Please let me know your idea.

Thanks,
John.

Govert van Drimmelen

unread,
Mar 14, 2017, 7:06:18 AM3/14/17
to exce...@googlegroups.com

Hi John,

 

You’ll probably have to implement this using the Excel-DNA Registration extension (https://github.com/Excel-DNA/Registration ), which would allow you to decide at runtime how to fill in the attribute information.

 

-Govert

--

You received this message because you are subscribed to the Google Groups "Excel-DNA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to exceldna+u...@googlegroups.com.
To post to this group, send email to exce...@googlegroups.com.

srinivas pitani

unread,
Aug 29, 2017, 9:40:20 AM8/29/17
to Excel-DNA
Hello Govert,

We are using excel dna version 0.32.5236, i am very new to this excel related work. In our maintenance application i have to resolve an issue related to localization. the issue is as follow,

Today() is working when i set my default language to English, but Russian user is using excel in Russia where my Today() function is failing (it seems all in-built and standard excel functions).

could you please help me on this.
Reply all
Reply to author
Forward
0 new messages