2016-05-19 11 views
1

私はC#でNetSuiteとの統合を実装しています。外部システムでは、NetSuiteの国リストに一致する国のリストを作成する必要があります。列挙値をコードと名前にリンクしたNetSuite国リストを取得しようとしています

NetSuiteのWebサービスは、あなたはまた、Webサービスから国の名前とコード(いえそうまっすぐでない前方方法で)のリストを取得することができます列挙コール国

public enum Country { 
    _afghanistan, 
    _alandIslands, 
    _albania, 
    _algeria, 
    ... 

を提供します。 (参照:http://suiteweekly.com/2015/07/netsuite-get-all-country-list/)を

をあなたは、このような値にアクセスすることができますどの:

  • アフガニスタン、AF
  • オーランド諸島、AX
  • アルバニア、AL
  • アルジェリア、DZ
  • アメリカサモア、AS
  • ...

ご覧のとおり、2つをリンクする方法はありません。 (私はインデックスで一致しようとしましたが、うまくいかず、うまくいきませんでした)

NetSuiteのヘルプファイルにはリストがあります。しかし、これは静的なものであり、NetSuitesのアップデートとして更新されるダイナミックなソリューションが本当に必要なのは、国々が変わることを知っているからです。

Screenshot of Country Enumerations from NetSuite help docs

私がオンライン発見した唯一の解決策は、2つのデータセットをマップする静的なデータを提供している人たちです。 (例:suiteweekly.com/2015/07/netsuite-complete-country-list-in-netsuite/

これは唯一の解決策ではないと思います。

これ以外の方にはより良い解決策がありますか?

あなたが読んでいるなら、あなたはプログラマーに休憩を与えてください。

答えて

2

私が思いついた最善の解決策は、国名と列挙キーの間の見かけの関係を利用して、2つの間のリンクを築くことです。私は他の人がこのソリューションで改善できると確信していますが、私が本当に見たいと思っているのは、明らかなパターンに依存するこのようなハックではなく、むしろ明示的な接続に基づいているソリューションです。あるいは、NetSuiteはデータを一箇所にまとめて提供するだけです。私は試合を偽造しようとすることができる少しのコードで>オーランド諸島

-

_alandIslands:あなたがここに明白な関係を見ることができる。例えば

まず列挙キーを配列に取得します。私は結果を保持するタイプのNetSuiteCountryのオブジェクトのリストを作成します。

var countryEnumKeys = Enum.GetNames(typeof(Country)); 
var countries = new List<NetSuiteCountry>(); 

私は上記の参照コード(ここには表示されていません)を使用して取得した国名とコードのリストをループします。

国名ごとに、Regex.Replaceで国名のすべての単語でない文字を取り除き、アンダースコア(_)を付けてから、文字列を小文字に変換します。最後に、Enumeration Key(小文字に変換されたもの)と作成された正規表現文字列の間の一致を見つけようとします。一致が見つかった場合は、すべてのデータを国別リストに保存します。

更新:コメントに基づいて、例外をハードコードすることなく異常を処理しようとするコード/ハッキングを追加しました。うまくいけば、これらのアップデートは将来のアップデートをキャッチしてくれるが、約束はない。この記事の執筆時点では、すべての既知の異常を処理することができました。私の場合、廃止された国を無視する必要があったので、それらは含まれていません。ここで

foreach (RecordRef baseRef in baseRefList) 
{ 
    var name = baseRef.name; 

    //Skip Deprecated countries 
    if (name.EndsWith("(Deprecated)")) continue; 

    //Use the name to try to find and enumkey match and only add a country if found. 
    var enumMatcher = $"_{Regex.Replace(name, @"\W", "").ToLower()}"; 

    //Compares Ignoring Case and Diacritic characters 
    var enumMatch = CountryEnumKeys.FirstOrDefault(e => string.Compare(e, enumMatcher, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0); 

    //Then try by Enum starts with Name but only one. 
    if (enumMatch == null) 
    { 
    var matches = CountryEnumKeys.Where(e => e.ToLower().StartsWith(enumMatcher)); 
    if (matches.Count() == 1) 
    { 
     Debug.Write($"- Country Match Hack 1 : "); 
     enumMatch = matches.First(); 
    } 
    } 

    //Then try by Name starts with Enum but only one. 
    if (enumMatch == null) 
    { 
    var matches = CountryEnumKeys.Where(e => enumMatcher.StartsWith(e.ToLower())); 
    if (matches.Count() == 1) 
    { 
     Debug.Write($"- Country Match Hack 2 : "); 
     enumMatch = matches.First(); 
    } 
    } 

    //Finally try by first half Enum and Name match but again only one. 
    if (enumMatch == null) 
    { 
    var matches = CountryEnumKeys.Where(e => e.ToLower().StartsWith(enumMatcher.Substring(0, (enumMatcher.Length/2)))); 
    if (matches.Count() == 1) 
    { 
     Debug.Write($"- Country Match Hack 3 : "); 
     enumMatch = matches.First(); 
    } 
    } 

    if (enumMatch != null) 
    { 
    var enumIndex = Array.IndexOf(CountryEnumKeys, enumMatch); 
    if (enumIndex >= 0) 
    { 
     var country = (Country) enumIndex; 
     var nsCountry = new NetSuiteCountry 
     { 
     Name = baseRef.name, 
     Code = baseRef.internalId, 
     EnumKey = country.ToString(), 
     Country = country 
     }; 

     Debug.WriteLine($"[{nsCountry.Name}] as [{nsCountry.EnumKey}]"); 
     countries.Add(nsCountry); 
    } 
    } 
    else 
    { 
    Debug.WriteLine($"Could not find Country match for: [{name}] as [{enumMatcher}]"); 
    } 
} 

は私のNetSuiteCountryクラスです:

public class NetSuiteCountry 
{ 
    public string Name { get; set; } 
    public string Code { get; set; } 
    public string EnumKey { get; set; } 
    public Country Country { get; set; } 
} 
+0

素敵なやり方で、あなたは素晴らしいテクニックを思いついた。あなたが他のコードを投稿できるかどうか不思議なことに、私はbaseRef.internalIdを持っていることに気付きました。私はハーフを行う前にその値を取得する方法を見つけようと半日も頭を悩ましていました。ありがとう。 –

1

は私が、私はコーダないよ免責事項から始めましょう、これは私がC#のを見て試してみた最初の日でありますプログラム。

私は、Netsuiteの会社名、コード、数値の完全なリストが必要なJavascriptプロジェクトに似たものが必要です。唯一の方法はWebサービスによるものと思われるヘルプを読むときです。

NetsuiteとVisual Studioのバージョンからwebservices用のサンプルアプリケーションをダウンロードしました。提供されたサンプルプログラムを編集して、すべての国名と国コード(カナダ、CAなど)のリストを作成できました。

私は国の名前のリストを取得するには、以前のポスターに似た何かをやって始まった:

string[] countryList = Enum.GetNames(typeof(Country)); 
foreach (string s in countryList) 
{ 
    _out.writeLn(s); 
} 

しかし、私はこの後の解消や新しい技術を始めました。前の回答と同様のクラスを作成しました:

public class NS_Country 
{ 
    public string countryCode { get; set; } 
    public string countryName { get; set; } 
    public string countryEnum { get; set; } 
    public string countryNumericID { get; set; } 
} 

ここに、会社名、コード、IDのリストを取得するための新しいコードがあります。私が実際にコーダーではなく、これがC#、たくさんのGoogle、切り取り/貼り付けによる私の最初の試みである前に、私が言及したように非常に効率的ではないことを認識しています。

_out.writeLn(" Attempting to get Country list."); 
// Create a list for the NS_Country objects 
List<NS_Country> CountryList = new List<NS_Country>(); 

// Create a new GetSelectValueFieldDescription object to use in a getSelectValue search 
GetSelectValueFieldDescription countryDesc = new GetSelectValueFieldDescription(); 
countryDesc.recordType = RecordType.customer; 
countryDesc.recordTypeSpecified = true; 
countryDesc.sublist = "addressbooklist"; 
countryDesc.field = "country"; 

// Create a GetSelectValueResult object to hold the results of the search 
GetSelectValueResult myResult = _service.getSelectValue(countryDesc, 0); 
BaseRef[] baseRef = myResult.baseRefList; 

foreach (BaseRef nsCountryRef in baseRef) 
{ 
    // Didn't know how to do this more efficiently 
    // Get the type for the BaseRef object, get the property for "internalId", 
    // then finally get it's value as string and assign it to myCountryCode 
    string myCountryCode = nsCountryRef.GetType().GetProperty("internalId").GetValue(nsCountryRef).ToString(); 

    // Create a new NS_Country object 
    NS_Country countryToAdd = new NS_Country 
    { 
     countryCode = myCountryCode, 
     countryName = nsCountryRef.name, 
     // Call to a function to get the enum value based on the name 
     countryEnum = getCountryEnum(nsCountryRef.name) 
    }; 
    try 
    { 
     // If the country enum was verified in the Countries enum 
     if (!String.IsNullOrEmpty(countryToAdd.countryEnum)) 
     { 
      int countryEnumIndex = (int)Enum.Parse(typeof(Country), countryToAdd.countryEnum); 
      Debug.WriteLine("Enum: " + countryToAdd.countryEnum + ", Enum Index: " + countryEnumIndex); 
      _out.writeLn("ID: " + countryToAdd.countryCode + ", Name: " + countryToAdd.countryName + ", Enum: " + countryToAdd.countryEnum); 
     } 
    } 
    // There was a problem locating the country enum that was not handled 
    catch (Exception ex) 
    { 
     Debug.WriteLine("Enum: " + countryToAdd.countryEnum + ", Enum Index Not Found"); 
     _out.writeLn("ID: " + countryToAdd.countryCode + ", Name: " + countryToAdd.countryName + ", Enum: Not Found"); 
    } 
    // Add the countryToAdd object to the CountryList 
    CountryList.Add(countryToAdd); 
} 
// Create a JSON - I need this for my javascript 
var javaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 
string jsonString = javaScriptSerializer.Serialize(CountryList); 
Debug.WriteLine(jsonString); 

列挙値を得るために、私はgetCountryEnumと呼ばれる関数を作成:私は機能、RemoveDiacritics I found hereを使用上記で

static string getCountryEnum(string countryName) 
{ 
    // Create a dictionary for looking up the exceptions that can't be converted 
    // Don't know what Netsuite was thinking with these ones ;D 
    Dictionary<string, string> dictExceptions = new Dictionary<string, string>() 
    { 
     {"Congo, Democratic Republic of", "_congoDemocraticPeoplesRepublic"}, 
     {"Myanmar (Burma)", "_myanmar"}, 
     {"Wallis and Futuna", "_wallisAndFutunaIslands"} 
    }; 

    // Replace with "'s" in the Country names with "s" 
    string countryName2 = Regex.Replace(countryName, @"\'s", "s"); 
    // Call a function that replaces accented characters with non-accented equivalent 
    countryName2 = RemoveDiacritics(countryName2); 
    countryName2 = Regex.Replace(countryName2, @"\W", " "); 

    string[] separators = {" ","'"}; // "'" required to deal with country names like "Cote d'Ivoire" 
    string[] words = countryName2.Split(separators, StringSplitOptions.RemoveEmptyEntries); 
    for (var i = 0; i < words.Length; i++) 
    { 
     string word = words[i]; 
     if (i == 0) 
     { 
      words[i] = char.ToLower(word[0]) + word.Substring(1); 
     } 
     else 
     { 
      words[i] = char.ToUpper(word[0]) + word.Substring(1); 
     } 
    } 
    string countryEnum2 = "_" + String.Join("", words); 

    // return an empty string if the country name contains Deprecated 
    bool b = countryName.Contains("Deprecated"); 
    if (b) 
    { 
     return String.Empty; 
    } 
    else 
    { 
     // test to see if the country name was one of the exceptions 
     string test; 
     bool isExceptionCountry = dictExceptions.TryGetValue(countryName, out test); 
     if (isExceptionCountry == true) 
     { 
      return dictExceptions[countryName]; 
     } 
     else 
     { 
      return countryEnum2; 
     } 
    } 
} 

を。私はCoutriesのすべての値を持っていたJSONオブジェクトを望んでいた私の目的のために

// Test tricky names 
Debug.WriteLine(getCountryEnum("Curaçao")); 
Debug.WriteLine(getCountryEnum("Saint Barthélemy")); 
Debug.WriteLine(getCountryEnum("Croatia/Hrvatska")); 
Debug.WriteLine(getCountryEnum("Korea, Democratic People's Republic")); 
Debug.WriteLine(getCountryEnum("US Minor Outlying Islands")); 
Debug.WriteLine(getCountryEnum("Cote d'Ivoire")); 
Debug.WriteLine(getCountryEnum("Heard and McDonald Islands")); 
// Enums that fail 
Debug.WriteLine(getCountryEnum("Congo, Democratic Republic of")); // _congoDemocraticPeoplesRepublic added to exceptions 
Debug.WriteLine(getCountryEnum("Myanmar (Burma)")); // _myanmar added to exceptions 
Debug.WriteLine(getCountryEnum("Netherlands Antilles (Deprecated)")); // Skip Deprecated 
Debug.WriteLine(getCountryEnum("Serbia and Montenegro (Deprecated)")); // Skip Deprecated 
Debug.WriteLine(getCountryEnum("Wallis and Futuna")); // _wallisAndFutunaIslands added to exceptions 

:ここ

static string RemoveDiacritics(string text) 
{ 
    string formD = text.Normalize(NormalizationForm.FormD); 
    StringBuilder sb = new StringBuilder(); 
    foreach (char ch in formD) 
    { 
     UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(ch); 
     if (uc != UnicodeCategory.NonSpacingMark) 
     { 
      sb.Append(ch); 
     } 
    } 
    return sb.ToString().Normalize(NormalizationForm.FormC); 
} 

は、あなたがして開発任意のソリューションをテストするためにトリッキーな例です:私は、以下で参照機能を再投稿します(名前、コード、列挙型、値)。誰かがそれを探している場合に備えて、ここにそれを含めます。数値は、Netsuiteのオンラインフォームに情報を転送する必要があるサードパーティのHTMLフォームがある場合に便利です。

Here is a link to the JSON object on Pastebin

私はプログラミング知識が不足していることを認識しています(本当に少しのJavaScriptしかありません)。この追加情報は誰かにとって有益です。

+0

Netsuiteが提供するサンプルプログラムについては、次のリファレンスも追加しました。using System.Web.Script.Serialization; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Text.RegularExpressions; –

関連する問題