Reputation: 2568
I am working on automating Word via Office.Interop
as part of a C# plugin.
I have a loop in my C# code that has only one function is to look up a string of a language's name in the collection of Word.Languages
and then once I have the ID for that language, I then assign it to the selection. Here is the code:
using Word = Microsoft.Office.Interop.Word;
Word.Application oWord = new Word.Application();
Word.Document oWordDoc = new Word.Document();
//Opening document here and doing stuff with it
var Selection = oWordDoc.ActiveWindow.Selection;
string strTgtLanguage="Hungarian";
var test = oWord.Application.Languages;
foreach (Word.Language item in test)
{
if (item.NameLocal.IndexOf(strTgtLanguage) > -1)
{
Selection.LanguageID = item.ID;
break;
}
}
It takes about 1 second per language to do the lookup. With over 250 items in the collection I am looking at 4 minutes for Xhosa and Zulu.
So I am trying to speed this up. As in the code, I apparently managed to gain some speed on assigning the collection to an object and doing the loop on that object, but it still in the same order of magnitude.
I have been researching some options on SO and otherwise, but I did not find any so far that would fit this specific situation. Maybe a LINQ query would be faster?
I wonder if somebody could help with this. Thanks.
Update
I was experimenting based on the answers and tried to make List
:
private class LanguageItem
{
public Word.WdLanguageID Id { get; set; }
public string Name { get; set; }
public LanguageItem(string name, int id)
{
Id = (Word.WdLanguageID)id;
Name = name;
}
}
public static class LanguageList
{
private List<LanguageItem> _languageList;
private LanguageList()
{
_languageList.Add(new LanguageItem("Arabic", 1025));
_languageList.Add(new LanguageItem("Bulgarian", 1026));
_languageList.Add(new LanguageItem("Catalan", 1027));
_languageList.Add(new LanguageItem("TraditionalChinese", 1028));
_languageList.Add(new LanguageItem("Czech", 1029));
_languageList.Add(new LanguageItem("Danish", 1030));
_languageList.Add(new LanguageItem("German", 1031));
_languageList.Add(new LanguageItem("Greek", 1032));
_languageList.Add(new LanguageItem("EnglishUS", 1033));
_languageList.Add(new LanguageItem("Spanish", 1034));
_languageList.Add(new LanguageItem("Finnish", 1035));
_languageList.Add(new LanguageItem("French", 1036));
_languageList.Add(new LanguageItem("Hebrew", 1037));
_languageList.Add(new LanguageItem("Hungarian", 1038));
_languageList.Add(new LanguageItem("Icelandic", 1039));
_languageList.Add(new LanguageItem("Italian", 1040));
_languageList.Add(new LanguageItem("Japanese", 1041));
_languageList.Add(new LanguageItem("Korean", 1042));
_languageList.Add(new LanguageItem("Dutch", 1043));
_languageList.Add(new LanguageItem("NorwegianBokmol", 1044));
_languageList.Add(new LanguageItem("Polish", 1045));
_languageList.Add(new LanguageItem("BrazilianPortuguese", 1046));
_languageList.Add(new LanguageItem("RhaetoRomanic", 1047));
_languageList.Add(new LanguageItem("Romanian", 1048));
_languageList.Add(new LanguageItem("Russian", 1049));
_languageList.Add(new LanguageItem("Croatian", 1050));
_languageList.Add(new LanguageItem("Slovak", 1051));
_languageList.Add(new LanguageItem("Albanian", 1052));
_languageList.Add(new LanguageItem("Swedish", 1053));
_languageList.Add(new LanguageItem("Thai", 1054));
_languageList.Add(new LanguageItem("Turkish", 1055));
_languageList.Add(new LanguageItem("Urdu", 1056));
_languageList.Add(new LanguageItem("Indonesian", 1057));
_languageList.Add(new LanguageItem("Ukrainian", 1058));
_languageList.Add(new LanguageItem("Byelorussian", 1059));
_languageList.Add(new LanguageItem("Slovenian", 1060));
_languageList.Add(new LanguageItem("Estonian", 1061));
_languageList.Add(new LanguageItem("Latvian", 1062));
_languageList.Add(new LanguageItem("Lithuanian", 1063));
_languageList.Add(new LanguageItem("Tajik", 1064));
_languageList.Add(new LanguageItem("Farsi", 1065));
_languageList.Add(new LanguageItem("Vietnamese", 1066));
_languageList.Add(new LanguageItem("Armenian", 1067));
_languageList.Add(new LanguageItem("AzeriLatin", 1068));
_languageList.Add(new LanguageItem("Basque", 1069));
_languageList.Add(new LanguageItem("Sorbian", 1070));
_languageList.Add(new LanguageItem("Macedonian", 1071));
_languageList.Add(new LanguageItem("Sesotho", 1072));
_languageList.Add(new LanguageItem("Sutu", 1072));
_languageList.Add(new LanguageItem("Tsonga", 1073));
_languageList.Add(new LanguageItem("Tswana", 1074));
_languageList.Add(new LanguageItem("Venda", 1075));
_languageList.Add(new LanguageItem("Xhosa", 1076));
_languageList.Add(new LanguageItem("Zulu", 1077));
_languageList.Add(new LanguageItem("Afrikaans", 1078));
_languageList.Add(new LanguageItem("Georgian", 1079));
_languageList.Add(new LanguageItem("Faeroese", 1080));
_languageList.Add(new LanguageItem("Hindi", 1081));
_languageList.Add(new LanguageItem("Maltese", 1082));
_languageList.Add(new LanguageItem("SamiLappish", 1083));
_languageList.Add(new LanguageItem("GaelicScotland", 1084));
_languageList.Add(new LanguageItem("Yiddish", 1085));
_languageList.Add(new LanguageItem("Malaysian", 1086));
_languageList.Add(new LanguageItem("Kazakh", 1087));
_languageList.Add(new LanguageItem("Kirghiz", 1088));
_languageList.Add(new LanguageItem("Kyrgyz", 1088));
_languageList.Add(new LanguageItem("Swahili", 1089));
_languageList.Add(new LanguageItem("Turkmen", 1090));
_languageList.Add(new LanguageItem("UzbekLatin", 1091));
_languageList.Add(new LanguageItem("Tatar", 1092));
_languageList.Add(new LanguageItem("Bengali", 1093));
_languageList.Add(new LanguageItem("Punjabi", 1094));
_languageList.Add(new LanguageItem("Gujarati", 1095));
_languageList.Add(new LanguageItem("Oriya", 1096));
_languageList.Add(new LanguageItem("Tamil", 1097));
_languageList.Add(new LanguageItem("Telugu", 1098));
_languageList.Add(new LanguageItem("Kannada", 1099));
_languageList.Add(new LanguageItem("Malayalam", 1100));
_languageList.Add(new LanguageItem("Assamese", 1101));
_languageList.Add(new LanguageItem("Marathi", 1102));
_languageList.Add(new LanguageItem("Sanskrit", 1103));
_languageList.Add(new LanguageItem("Mongolian", 1104));
_languageList.Add(new LanguageItem("Tibetan", 1105));
_languageList.Add(new LanguageItem("Welsh", 1106));
_languageList.Add(new LanguageItem("Khmer", 1107));
_languageList.Add(new LanguageItem("Lao", 1108));
_languageList.Add(new LanguageItem("Burmese", 1109));
_languageList.Add(new LanguageItem("Galician", 1110));
_languageList.Add(new LanguageItem("Konkani", 1111));
_languageList.Add(new LanguageItem("Manipuri", 1112));
_languageList.Add(new LanguageItem("Sindhi", 1113));
_languageList.Add(new LanguageItem("Syriac", 1114));
_languageList.Add(new LanguageItem("Sinhalese", 1115));
_languageList.Add(new LanguageItem("Cherokee", 1116));
_languageList.Add(new LanguageItem("Inuktitut", 1117));
_languageList.Add(new LanguageItem("Amharic", 1118));
_languageList.Add(new LanguageItem("Tamazight", 1119));
_languageList.Add(new LanguageItem("Kashmiri", 1120));
_languageList.Add(new LanguageItem("Nepali", 1121));
_languageList.Add(new LanguageItem("FrisianNetherlands", 1122));
_languageList.Add(new LanguageItem("Pashto", 1123));
_languageList.Add(new LanguageItem("Filipino", 1124));
_languageList.Add(new LanguageItem("Divehi", 1125));
_languageList.Add(new LanguageItem("Edo", 1126));
_languageList.Add(new LanguageItem("Fulfulde", 1127));
_languageList.Add(new LanguageItem("Hausa", 1128));
_languageList.Add(new LanguageItem("Ibibio", 1129));
_languageList.Add(new LanguageItem("Yoruba", 1130));
_languageList.Add(new LanguageItem("Igbo", 1136));
_languageList.Add(new LanguageItem("Kanuri", 1137));
_languageList.Add(new LanguageItem("Oromo", 1138));
_languageList.Add(new LanguageItem("TigrignaEthiopic", 1139));
_languageList.Add(new LanguageItem("Guarani", 1140));
_languageList.Add(new LanguageItem("Hawaiian", 1141));
_languageList.Add(new LanguageItem("Latin", 1142));
_languageList.Add(new LanguageItem("Somali", 1143));
_languageList.Add(new LanguageItem("Yi", 1144));
_languageList.Add(new LanguageItem("ArabicIraq", 2049));
_languageList.Add(new LanguageItem("SimplifiedChinese", 2052));
_languageList.Add(new LanguageItem("SwissGerman", 2055));
_languageList.Add(new LanguageItem("EnglishUK", 2057));
_languageList.Add(new LanguageItem("MexicanSpanish", 2058));
_languageList.Add(new LanguageItem("BelgianFrench", 2060));
_languageList.Add(new LanguageItem("SwissItalian", 2064));
_languageList.Add(new LanguageItem("BelgianDutch", 2067));
_languageList.Add(new LanguageItem("NorwegianNynorsk", 2068));
_languageList.Add(new LanguageItem("Portuguese", 2070));
_languageList.Add(new LanguageItem("RomanianMoldova", 2072));
_languageList.Add(new LanguageItem("RussianMoldova", 2073));
_languageList.Add(new LanguageItem("SerbianLatin", 2074));
_languageList.Add(new LanguageItem("SwedishFinland", 2077));
_languageList.Add(new LanguageItem("AzeriCyrillic", 2092));
_languageList.Add(new LanguageItem("GaelicIreland", 2108));
_languageList.Add(new LanguageItem("MalayBruneiDarussalam", 2110));
_languageList.Add(new LanguageItem("UzbekCyrillic", 2115));
_languageList.Add(new LanguageItem("DzongkhaBhutan", 2129));
_languageList.Add(new LanguageItem("SindhiPakistan", 2137));
_languageList.Add(new LanguageItem("TamazightLatin", 2143));
_languageList.Add(new LanguageItem("TigrignaEritrea", 2163));
_languageList.Add(new LanguageItem("ArabicEgypt", 3073));
_languageList.Add(new LanguageItem("ChineseHongKongSAR", 3076));
_languageList.Add(new LanguageItem("GermanAustria", 3079));
_languageList.Add(new LanguageItem("EnglishAUS", 3081));
_languageList.Add(new LanguageItem("SpanishModernSort", 3082));
_languageList.Add(new LanguageItem("FrenchCanadian", 3084));
_languageList.Add(new LanguageItem("SerbianCyrillic", 3098));
_languageList.Add(new LanguageItem("ArabicLibya", 4097));
_languageList.Add(new LanguageItem("ChineseSingapore", 4100));
_languageList.Add(new LanguageItem("GermanLuxembourg", 4103));
_languageList.Add(new LanguageItem("EnglishCanadian", 4105));
_languageList.Add(new LanguageItem("SpanishGuatemala", 4106));
_languageList.Add(new LanguageItem("SwissFrench", 4108));
_languageList.Add(new LanguageItem("ArabicAlgeria", 5121));
_languageList.Add(new LanguageItem("ChineseMacaoSAR", 5124));
_languageList.Add(new LanguageItem("GermanLiechtenstein", 5127));
_languageList.Add(new LanguageItem("EnglishNewZealand", 5129));
_languageList.Add(new LanguageItem("SpanishCostaRica", 5130));
_languageList.Add(new LanguageItem("FrenchLuxembourg", 5132));
_languageList.Add(new LanguageItem("ArabicMorocco", 6145));
_languageList.Add(new LanguageItem("EnglishIreland", 6153));
_languageList.Add(new LanguageItem("SpanishPanama", 6154));
_languageList.Add(new LanguageItem("FrenchMonaco", 6156));
_languageList.Add(new LanguageItem("ArabicTunisia", 7169));
_languageList.Add(new LanguageItem("EnglishSouthAfrica", 7177));
_languageList.Add(new LanguageItem("SpanishDominicanRepublic", 7178));
_languageList.Add(new LanguageItem("FrenchWestIndies", 7180));
_languageList.Add(new LanguageItem("ArabicOman", 8193));
_languageList.Add(new LanguageItem("EnglishJamaica", 8201));
_languageList.Add(new LanguageItem("SpanishVenezuela", 8202));
_languageList.Add(new LanguageItem("FrenchReunion", 8204));
_languageList.Add(new LanguageItem("ArabicYemen", 9217));
_languageList.Add(new LanguageItem("EnglishCaribbean", 9225));
_languageList.Add(new LanguageItem("SpanishColombia", 9226));
_languageList.Add(new LanguageItem("FrenchZaire", 9228));
_languageList.Add(new LanguageItem("ArabicSyria", 10241));
_languageList.Add(new LanguageItem("EnglishBelize", 10249));
_languageList.Add(new LanguageItem("SpanishPeru", 10250));
_languageList.Add(new LanguageItem("FrenchSenegal", 10252));
_languageList.Add(new LanguageItem("ArabicJordan", 11265));
_languageList.Add(new LanguageItem("EnglishTrinidadTobago", 11273));
_languageList.Add(new LanguageItem("SpanishArgentina", 11274));
_languageList.Add(new LanguageItem("FrenchCameroon", 11276));
_languageList.Add(new LanguageItem("ArabicLebanon", 12289));
_languageList.Add(new LanguageItem("EnglishZimbabwe", 12297));
_languageList.Add(new LanguageItem("SpanishEcuador", 12298));
_languageList.Add(new LanguageItem("FrenchCotedIvoire", 12300));
_languageList.Add(new LanguageItem("ArabicKuwait", 13313));
_languageList.Add(new LanguageItem("EnglishPhilippines", 13321));
_languageList.Add(new LanguageItem("SpanishChile", 13322));
_languageList.Add(new LanguageItem("FrenchMali", 13324));
_languageList.Add(new LanguageItem("ArabicUAE", 14337));
_languageList.Add(new LanguageItem("EnglishIndonesia", 14345));
_languageList.Add(new LanguageItem("SpanishUruguay", 14346));
_languageList.Add(new LanguageItem("FrenchMorocco", 14348));
_languageList.Add(new LanguageItem("ArabicBahrain", 15361));
_languageList.Add(new LanguageItem("SpanishParaguay", 15370));
_languageList.Add(new LanguageItem("FrenchHaiti", 15372));
_languageList.Add(new LanguageItem("ArabicQatar", 16385));
_languageList.Add(new LanguageItem("SpanishBolivia", 16394));
_languageList.Add(new LanguageItem("SpanishElSalvador", 17418));
_languageList.Add(new LanguageItem("SpanishHonduras", 18442));
_languageList.Add(new LanguageItem("SpanishNicaragua", 19466));
_languageList.Add(new LanguageItem("SpanishPuertoRico", 20490));
}
public List<LanguageItem> GetLanguageList
{
get
{
return _languageList;
}
private set
{
_languageList = value;
}
}
}
This is still to be refined.
Upvotes: 0
Views: 377
Reputation: 1740
I think the issue is that you are iterating over data via COM everytime. If you store the languages in a list the first time you access them, you can then use the list each time - without accessing via COM.
Here is an example to demonstrate, store the list of languages once (if you are calling this multiple times). I used "Spanish (Latin American)" because it was the last in my list retrieved.
I've included stopwatches just to show the times of the different stages and lookups.
using Word = Microsoft.Office.Interop.Word;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
namespace TestWordLanguages
{
public class OfficeLanguages
{
private class LanguageItem
{
public Word.WdLanguageID Id { get; set; }
public string Name { get; set; }
public LanguageItem(Word.WdLanguageID id, string name)
{
Id = id;
Name = name;
}
}
List<LanguageItem> languageList = new List<LanguageItem>();
public void MethodA()
{
Stopwatch sw1 = new Stopwatch();
Stopwatch sw2 = new Stopwatch();
Stopwatch sw3 = new Stopwatch();
sw1.Start();
Word.Application oWord = new Word.Application();
Word.Document oWordDoc = new Word.Document();
//Opening document here and doing stuff with it
var Selection = oWordDoc.ActiveWindow.Selection;
string strTgtLanguage = "Spanish (Latin America)";
var test = oWord.Application.Languages;
if (languageList.Count == 0)
{
foreach (Word.Language item in test)
{
languageList.Add(new LanguageItem(item.ID, item.NameLocal));
}
}
sw1.Stop(); // End of initial setup
sw2.Start(); // Current lookup - using COM everytime
foreach (Word.Language item in test)
{
if (item.NameLocal.IndexOf(strTgtLanguage) > -1)
{
Selection.LanguageID = item.ID;
break;
}
}
sw2.Stop();
sw3.Start(); // Using stored list of languages
Selection.LanguageID = languageList.Single(lang => lang.Name == strTgtLanguage).Id;
sw3.Stop();
}
}
}
I thought you may want to repeatedly lookup the language, which is why I suggested placing the values in a list.
However, if you will be using the same server (and installation of MS Word) for the application, you can perform the initial lookup, get the values and embed them (or use a Resource File) to store them for use.
If however, this application will be placed on different client machines/servers, then the lookup will have to be made on each installation at least once - and then stored for future use in the application
When I tested this locally, it took around 500ms to generate the list or look through for the the last entry. If your application is looking up the values using COM over a network connection, that may be the reason for the extra slowness...
Upvotes: 1