Сделать .NET DLL COM видимым и пригодным для использования в VBA ⇐ C#

Место общения программистов C#
Anonymous
Сделать .NET DLL COM видимым и пригодным для использования в VBA

Сообщение Anonymous »

В нашем офисе мы широко используем VBA и часто делимся модулями в нескольких проектах. Теперь, когда наша команда выросла, и мы управляем большим количеством проектов, я хотел бы сделать эти общие функции более доступными. В идеале мы могли бы ссылаться на них как на библиотеку - например, перейдя в VBA → «Инструменты» → «Ссылки» и, включив что -то вроде «rafleAddress 1.0». Этот подход значительно облегчит поддержание и обновление общего кода, поскольку любые изменения должны быть внесены только в одном месте. Теперь я работаю над тем, чтобы сделать код доступным для объектов COM и регистрации DLL. На данный момент я не уверен, как продолжить. Ниже приведен код, который у меня есть до сих пор. < /P>

Код: Выделить всё

'''
using System;

namespace CorrectAddress
{
class AddressCorrector
{
// make an array of abbreviations and references full forms for provinces
static readonly (string ProvinceAbbreviation, string Province)[] Provinces = new[]
{
("AB","ALBERTA"),
("BC","BRITISH COLUMBIA"),
("MB","MANITOBA"),
("NB","NEW BRUNSWICK"),
("NL","NEWFOUNDLAND AND LABRADOR"),
("NS","NOVA SCOTIA"),
("ON","ONTARIO"),
("PE","PRINCE EDWARD ISLAND"),
("QC","QUEBEC"),
("SK","SASKATCHEWAN"),
("NT","NORTHWEST TERRITORIES"),
("NU","NUNAVUT"),
("YT","YUKON")
};

//makes an array of full streets
static readonly string[] FullForms = new[]
{
"STREET",      // 0
"ROAD",        // 1
"BOULEVARD",   // 2
"DRIVE",       // 3
"LANE",        // 4
"PARKWAY",     // 5
"COURT",       // 6
"CIRCLE",      // 7
"TERRACE",     // 8
"PLACE",       // 9
"SQUARE",      // 10
"TRAIL",       // 11
"CRESCENT",    // 12
"HIGHWAY",     // 13
"EXPRESSWAY",  // 14
"ALLEY",       // 15
"GARDENS",     // 16
"CROSSING",    // 17
"VIEW",        // 18
"POINT",       // 19
"MOUNT",       // 20
"FORK",        // 21
"HEIGHTS",     // 22
"GLEN",        // 23
"HOLLOW",      // 24
"KNOLL",       // 25
"MEADOW",      // 26
"PLAINS",      // 27
"RIDGE",       // 28
"RIVER",       // 29
"SHORES",      // 30
"SPRINGS",     // 31
"SUMMIT",      // 32
"VALLEY",      // 33
"VILLAGE",     // 34
"VISTA",        // 35
"AVENUE"     //36
};

// make an array of abbreviations and references full forms
static readonly (string StreetAbbreviation, int FullFormIndex)[] StreetDescriptorMapping = new[]
{
("AVE",36),
("ST", 0),
("RD", 1),
("BLVD", 2),
("DR", 3),
("LN", 4),
("PKY", 5),
("PKWY", 5),
("CT", 6),
("CRT", 6),
("CTR", 6),
("CIR", 7),
("TER", 8),
("PL", 9),
("SQ", 10),
("TRL", 11),
("CRES", 12),
("HWY", 13),
("EXP", 14),
("EXPWY", 14),
("EXPW", 14),
("ALY", 15),
("GDNS", 16),
("XING", 17),
("VW", 18),
("PT", 19),
("MT", 20),
("MNT", 20),
("FRK", 21),
("HTS", 22),
("GLN", 23),
("HOL", 24),
("HOLW", 24),
("KNL", 25),
("MDW", 26),
("PLNS", 27),
("RDG", 28),
("RIV", 29),
("SHR", 30),
("SPGS", 31),
("SMT", 32),
("VLY", 33),
("VLG", 34),
("VIS", 35)
};

static readonly string[] UnitDescriptors = new[]
{
("BASEMENT"),
("LOWER"),
("UPPER"),
("MAIN"),
("TOP FLOOR"),
("PENTHOUSE"),
("GROUND FLOOR"),
("MEZZANINE"),
("ATTIC"),
};

static readonly string[] UnitReplacements = new[]
{
("UNIT"),
("APARTMENT"),
("UPPER"),
("APT"),
("SUITE"),
("LEVEL"),
("RURAL ROUTE"),
("MEZZANINE"),
("ATTIC"),
};

//corrects and changes dhort form to full form ST->STREET   once one replacement is found it returns it
static string CorrectStreetDescriptor(string Address)
{
//loops througgh list of abbreviations
foreach (var (StreetAbbreviation, fullFormIndex) in StreetDescriptorMapping)
{
//for each abbreviation it does case true
switch (true)
{
//eg. Ave takes " Ave," and replaces with " AVENUE,"
case bool _ when Address.Contains(" " + StreetAbbreviation + ",", StringComparison.OrdinalIgnoreCase):
{
Address = Address.Replace(" " + StreetAbbreviation + ",", " " + FullForms[fullFormIndex] + ",");
return Address;
}

//eg. Ave takes " Ave " and replaces with " AVENUE "
case bool _ when Address.Contains(" " + StreetAbbreviation + " ", StringComparison.OrdinalIgnoreCase):
{
Address = Address.Replace(" " + StreetAbbreviation + " ", " " + FullForms[fullFormIndex] + " ");
return Address; ;
}

//eg.  Ave takes " Ave." and replaces with " AVENUE"
case bool _ when Address.Contains(" " + StreetAbbreviation + ".", StringComparison.OrdinalIgnoreCase):
{
Address = Address.Replace(" " + StreetAbbreviation + ".", " " + FullForms[fullFormIndex]);
return Address;
}
}
}
return Address;
}

static bool IsStreet(string StreetCheck)
{
foreach (var streetType in FullForms)
{
if (StreetCheck.Contains(streetType, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}

static string CorrectProvince(string ProvinceForCorrection)
{
//loops througgh list of abbreviations
foreach (var (ProvinceAbbreviation, Province) in Provinces)
{
//for each abbreviation it does case true
if (ProvinceForCorrection.ToUpper() == Province.ToUpper())
{
return ProvinceAbbreviation;
}
}
return ProvinceForCorrection;
}

static string ReplaceUnits(string UnittoCorrect)
{
foreach (var Replacement in UnitReplacements)
{
if (UnittoCorrect.Contains(Replacement,StringComparison.OrdinalIgnoreCase))
{
UnittoCorrect = UnittoCorrect.Replace(Replacement, "", StringComparison.OrdinalIgnoreCase).Trim();
break;
}
}
return UnittoCorrect;
}

static (string Street,string Unit) SplitUnitandStreet(string StreettoCorrect,string UnittoCorrect)
{
foreach (var Descriptor in UnitDescriptors)
{
if (StreettoCorrect.EndsWith(Descriptor, StringComparison.OrdinalIgnoreCase))
{
// Remove the descriptor from the end of the street string
StreettoCorrect = StreettoCorrect.Substring(0, StreettoCorrect.Length - Descriptor.Length).Trim();

if (string.IsNullOrWhiteSpace(UnittoCorrect))
{
UnittoCorrect = Descriptor;
}
else
{
UnittoCorrect = UnittoCorrect + " " + Descriptor;
}
break;
}
}

if (UnittoCorrect == "")
{
string[] StreetSplit = StreettoCorrect.Split(" ");
int UpperBound = StreetSplit.Length - 1;
if (StreetSplit[UpperBound].All(char.IsDigit))
{
if (!(StreetSplit[UpperBound - 1] == "HIGHWAY") && !(StreetSplit[UpperBound - 2] + " " + StreetSplit[UpperBound - 1] == "COUNTY ROAD"))
{
UnittoCorrect = StreetSplit[UpperBound];
StreettoCorrect = ReplaceUnits(string.Join(" ", StreetSplit.Take(UpperBound)));

}
}
else
{
if (StreetSplit[0].Any(char.IsLetter) && !StreetSplit[0].All(char.IsLetter))
{
string StreetNumber = "";
foreach (char c in StreetSplit[0])
{
if (char.IsDigit(c))
{
StreetNumber = StreetNumber + c;
}
else
{
UnittoCorrect = UnittoCorrect + c;
}
}
StreetSplit[0] = StreetNumber;
StreettoCorrect = string.Join("  ", StreetSplit.Take(StreettoCorrect.Length));
}
}
}
else
{
UnittoCorrect = ReplaceUnits(UnittoCorrect);
}
return (StreettoCorrect,UnittoCorrect);
}

static string split_address(string Address)
{
//replace all double commas and number signs
Address = Address.Replace("#", "");
Address = Address.Replace(",,", "");
Address = Address.Replace(", ,", "");

//convert address to uppercase
Address = Address.ToUpper();

//return the correct street descriptor
Address = CorrectStreetDescriptor(Address);

string Street = "";
string Unit = "";
string City = "";
string Province = "";
string PostalCode = "";

string[] textSplitter = Address.Split(',', StringSplitOptions.None);
int upperBound = textSplitter.Length - 1;

//if proper address
if (upperBound >= 2)
{
textSplitter[upperBound] = textSplitter[upperBound].Replace("-", "").Trim();
string temporaryPostalCode = textSplitter[upperBound].Replace(" ", "");

if (temporaryPostalCode.Length == 6)
{
PostalCode = temporaryPostalCode;
Array.Resize(ref textSplitter, upperBound);
upperBound = upperBound - 1;
Province = CorrectProvince(textSplitter[upperBound].Trim());
}
else
{

PostalCode = temporaryPostalCode.Substring(temporaryPostalCode.Length - 6);

// Get the first 3 characters (e.g.  "N3L")
string fsa = PostalCode.Substring(0, 3);
int index = temporaryPostalCode.IndexOf(fsa, StringComparison.OrdinalIgnoreCase);
Province = CorrectProvince(temporaryPostalCode.Substring(0, index).Trim());
}

//resize array to erase ubound
Array.Resize(ref textSplitter, upperBound);
upperBound = upperBound - 1;

//get city and resize array
City = textSplitter[upperBound].Trim();
Array.Resize(ref textSplitter, upperBound);
upperBound = upperBound - 1;

//start to get street and unit
if (upperBound == 1) //2 variables street and unit
{
if (IsStreet(textSplitter[upperBound]))
{
Street = textSplitter[upperBound].Trim().ToUpper();
Array.Resize(ref textSplitter, upperBound);
upperBound = textSplitter.Length - 1;
Unit = textSplitter[upperBound].Trim().ToUpper();
}
else
{
Unit = textSplitter[upperBound].Trim().ToUpper();
Array.Resize(ref textSplitter, upperBound);
upperBound = textSplitter.Length - 1;
Street = textSplitter[upperBound].Trim().ToUpper();
}
}
else //1 street+unit or street
{
if (textSplitter[upperBound].Contains("-"))
{
string[] secondarySplitter = textSplitter[upperBound].Split('-', StringSplitOptions.None);
Street = secondarySplitter[1].Trim().ToUpper();
Unit = secondarySplitter[0].Trim().ToUpper();
}
else
{
Street = textSplitter[upperBound].Trim().ToUpper();
}
}

//checks a bit of logic for if unit is the street number
if (!Street.Any(char.IsDigit) && Unit.All(char.IsDigit))
{
if (Street.Contains("Rural Route", StringComparison.OrdinalIgnoreCase) ||
Street == "RR" ||
Street.Contains("POBOX", StringComparison.OrdinalIgnoreCase) ||
Street.Contains("BOX", StringComparison.OrdinalIgnoreCase) ||
Street.Contains("PO BOX", StringComparison.OrdinalIgnoreCase))
{
Street = $"{Street} {Unit}";
Unit = "";
}
else
{
Street = $"{Unit} {Street}";
Unit = "";
}
}
//checks if unti and street are flipped
else if (!Street.Any(char.IsDigit) && !Unit.All(char.IsDigit) && Unit.Any(char.IsDigit))
{
string tempUnit = Street;
string tempStreet = Unit;
Street = tempStreet;
Unit = tempUnit;
}

(Street, Unit) = SplitUnitandStreet(Street,Unit);
}

//returns the split address
return $"{Street},{Unit},{City},{Province},{PostalCode}";
}

static void Main()
{
Console.WriteLine(split_address("3680 KEELE ST, NORTH YORK, ON, M3J1M2"));
}
}
}
'' '
Для справки я разрабатываю в VS-коде с расширением C# dev и Dotnet

Подробнее здесь: https://stackoverflow.com/questions/796 ... ble-in-vba

Вернуться в «C#»