閱讀英文

共用方式為


建立支援多種語言的解決方案

Microsoft Dataverse 支援多種語言。 如果您需希望您的解決方案為組織安裝,且包含不同的基礎語言或多種語言,請在配置解決方案時考慮此做法。 下表列出使用方案元件的策略,包含支援多種語言的解決方案。

策略 解決方案元件類型
字串 (RESX) Web 資源 Web 資源
嵌入式標籤 應用程式導覽 (網站地圖)
功能區
匯出和導入翻譯 屬性
圖表​​
儀表板​​
Entity
實體關聯
表單
訊息
選項集
檢視次數
基本語言字串中的當地語系化 合約範本
關係角色
程序(工作流程)
資訊安全角色
欄位安全性設定檔
不需要當地語系化 SDK 訊息處理步驟
服務端點
每種語言的單獨元件 文章範本
電子郵件範本
合併列印範本
報告
對話方塊
將 XML Web 資源用作語言資源 外掛程式組件

下列段落提供各種策略的其他詳細資料。

字串(RESX)Web 資源

字串(RESX)web 資源加上 Dataverse 開發人員一起使用,在建立支援多種語言的 web 資源時能擁有更健全的選項。 其他資訊:字串(RESX)Web 資源

內嵌索引標籤

使用此銷售技術的每個解決方案元件需要所有包含在解決方案元件中的當地語系化文字。

功能區

安裝語言套件後,應用程式功能區自動顯示所功能區預設文字的當地語系化文字。 系統標籤定義在 ResourceId 屬性值中,僅供內部使用。 當您自己新增文字時,應使用 <LocLabels> 元素為您提供支援語言翻譯的文字。 其他資訊:使用功能區的當地語系化標籤

SiteMap

安裝語言套件後,預設文字會顯示在應用程式導覽列中,自動顯示翻譯文字。 如果要覆寫預設文字或提供您設定的文字,請使用 <Titles>元素。 Titles 元素應包含一個 <Title> 元素,其中含有解決方案支援的各種語言的翻譯的文字。 如果 Title 元素無法提供使用者慣用語言使用,則與組織基礎語言相應的標題就會顯示。

<SubArea> 元素允許透過使用者的語言偏好,使用的是 userlcid 參數,如此一來 SubArea.Url 屬性目標的內容就可以由使用者的語言偏好感知,並依此做調整。 其他資訊:傳遞參數至使用網站地圖的 URL

匯出和匯入翻譯

下表中的解決方案元件的當地語系化的標籤可用於本地化匯出。

實體 屬性 關聯
全域選項組 實體訊息 實體表單
實體檢視表 (SavedQuery) 圖表​​ 儀表板​​

翻譯標籤並顯示字串

您只能透過使用基礎語言在應用程式中執行自訂項目。 因此,當您要提供翻譯的索引標籤,並為這些字定項目顯示字串,您必須匯出索引標籤的文字,如此才能針對其他組織使用的語言進行翻譯。 使用下列步驟:

  1. 確定您的組織已安裝所有 MUI 套件以及要提供轉換為語言佈建語言。

  2. 您建立的解決方案元件與修改。

  3. 完成開發您自己的解決方案後,使用「匯出轉換」功能。 這會產生一個包含所有需要翻譯之索引標籤的 Office Excel 試算表 (CrmTranslations.xml)。

  4. 在試算表中提供了可對應的翻譯。

  5. 將翻譯匯回相同的 Dataverse 組織,使用「匯入翻譯」功能並發行變更。

  6. 下次解決方案匯出,會帶有您提供的任何翻譯。

    在匯入解決方案時,目標系統中無法使用語言標籤,在登入時會警告您此標籤已捨棄。

    如果目標系統的解決方案套件未提供基礎語言索引標籤,則會使用來源的基礎語言的標籤。 例如,如果匯入包含以英文做為基礎語言的英文及法文標籤的解決方案,但是目標系統使用日文為基礎語言,包含日文與法文,則會使用英文而非日文。 基礎語言索引標籤無法為 null 或空白。

正在匯出翻譯

在您輸出翻譯之前,您必須先安裝語言套件與佈建要翻譯的所有語言。 您可以匯出要翻譯在 Web 應用程式或透過使用 ExportTranslationRequest 訊息。 如需詳細資訊,請參閱匯出自訂實體和欄位文字以供翻譯

翻譯文字

如果您已在 Office Excel 開啟 CrmTranslations.xml 檔案,您會看到下表列出的三份工作表。

工作表 描述
資訊 顯示有關組織與解決方案的資訊,標籤與字串從解決方案中匯出。
顯示字串 顯示代表與中繼資料元件關聯的任何訊息文字的字串。 下表包含用於系統功能區元素的錯誤訊息和字串。
當地語系化標籤 顯示所有中繼資料元件標籤的文字。

您可以傳送此檔案給語言專家、翻譯社或在地化公司。 將需要為任何空白儲存格提供翻譯的字串。

注意

對於自訂實體,有些一般與系統實體共用的索引標籤,例如 建立時間建立者。 因為您已經安裝與佈建語言,但是,如果您匯出預設解決方案的語言,您可以在自訂實體中用翻譯的文字比對部分索引標籤,針對其他實體使用的識別標籤。 這可減少本地化成本並提升一致性。

在工作表內的文字翻譯完後,將 CrmTranslations.xml 和 [Content_Types].xml 檔案一起新增至同一個 .zip 壓縮檔中。 您現在可以匯入這個檔案了。

如果您偏好用程式將檔案匯出為 XML 文件,請參閱 Word、Excel 和 PowerPoint 的標準支援 以瞭解這些檔案使用的結構描述。

匯入翻譯的文字

重要

您可以只把翻譯的文字匯入組織 (先前匯出的組織)。

匯出自訂實體或屬性文字並進行翻譯之後,就可以匯入翻譯的文字字串,使用的是 ImportTranslationRequest 訊息。 匯入檔案必須包含 CrmTranslations.xml 和壓縮檔 [Content_Types].xml 檔案頁面。 如需詳細資訊,請參閱匯入翻譯實體和欄位文字

匯入完成的翻譯之後,會將自訂的語文顯示給使用譯文語言的使用者。

注意

Dataverse 無法匯入長度超過 500 個字元的翻譯文字。 如果翻譯檔案中任何項目的長度超過 500 個字元,則匯入程序失敗。 如果匯入程序失敗,請檢閱檔案中造成失敗的那一行,並減少字元數目,然後試著重新匯入。

因為只有基礎語言才能支援自訂,所以使用 Dataverse 時可以將基礎語言設定為您的慣用語言。 若要確認翻譯的文字會顯示,您必須變更 Dataverse 使用者介面的語言喜好設定。 若要執行其他自訂工作,您必須變更回基礎語言。

在基礎語言字串的本地化

某些解決方案元件不支援多種語言。 包括名稱或文字的元件只在特定語言中有意義。 如果您建立特定語言的解決方案,請定義所用組織基礎語言的解決方案元件。

如需支援多種語言,有一種使用基礎語言字串包含在地化的策略。 例如,如果您有名為「朋友」的關聯角色,而您需要備份英文、西班牙文與德文,您可以使用文字「朋友 (Amigo/Freund)」為關聯角色的名稱。 因為文字長度問題,所以有一些關於最多可以支援幾種語言的策略。

某些在此群組中的解決方案元件,僅系統管理員可看到。 因為系統的自訂只能在組織基礎語言中完成,並不需要提供多種語言版本。 Security RolesField Security Profile 元件屬於此組。

Contract Templates 提供一種服務合同類型的描述。 以下 名稱 以及 縮寫 欄位的文字。 您應考慮使用供組織中的所有使用者使用的唯一且適當的名稱和縮寫。

連接角色 依賴於選擇描述性連接角色類別和名稱的人員。 因為這些可以是相對的簡短,建議您在基礎語言字串包括本地化。

為事件啟動的流程(工作流) 可以正常工作,只要它們不需要使用要本地化的文本更新記錄。 可以使用工作流程組譯碼,因此可套用至翻譯文字的邏輯也可以使用相同的策略,視為外掛程式組譯碼使用 XML Web 資源作為語言資源

On-Demand 工作流 需要一個名稱,以便使用者可以選擇它們。 除了將本地化併入指定工作流程外,另一種策略為建立多個工作流程搭配翻譯的名稱,每個名稱都會呼叫子程序。 不過,所有使用者將看見指定工作流程的完整清單,而不只是使用者偏好的使用者介面語言。

不需要翻譯

SDK 消息處理步驟Service 端點 解決方案元件不會向使用者公開可本地化的文本。 如果很重要的,這些元件的名稱和描述對應組織的基礎語言,您可以使用該語言的名稱和描述建立並輸出受管理的解決方案。

每種語言的不同元件

下列解決方案元件都包含相當量要翻譯的文字:

  • 文章範本

  • 電子郵件範本

  • 合併列印範本

  • 報表

  • 對話方塊

    針對解決方案元件的類型,建議的策略是建立每種語言的不同元件。 這表示您通常會建立含有您的核心解決方案元件,然後不同受管理的解決方案包含每種語言,這些解決方案元件的基本受管理的解決方案。 在客戶安裝基本解決方案之後,即可安裝他們為組織提供的語言的受管理的解決方案。

    不像是程序 (工作流程),您可以建立對話方塊,反映使用者目前的語言喜好設定,而且只顯示對話方塊給該語言的使用者。

建立當地語系化對話方塊

  1. 安裝適當的語言套件並佈建語言。

    如需詳細資訊,請參閱語言套件安裝指示

  2. 變更您的個人選項來指定您需要對話方塊顯示的使用者介面語言

  3. 前往 設定 然後在 程序中心 群組,選擇 程序

  4. 按一下 新增 並在您指定的語言中建立對話方塊。

  5. 在建立對話方塊後,請變更您的個人選項,以指定組織的基礎語言。

  6. 在使用組織基礎語言時,您可以前往 設定 中的 解決方案 區域並新增翻譯對話方塊做為一部分的解決方案。

    此建立於其他語言中的對話方塊只會顯示 Dataverse 給該使用該語言的使用者。

使用 XML Web 資源做為語言資源

外掛程式組件解決方案元件可以透過送出 InvalidPluginExecutionException 以及建立和更新記錄傳送訊息給最後使用者。 不同於 Silverlight Web 資源,外掛程式無法使用資源檔案。

當外掛程式要求翻譯文字後,您可以使用 XML Web 資源儲存當地語系化字串,這樣外掛程式就可以在需要時存取它們。 您可選擇 XML 的結構,但是您可能會想要依照 ASP.NET 資源(.resx)檔案所使用的結構,來為每個語言建立分別的 XML web 資源。 例如,以下是名為 localizedString.en_US 的 XML web 資源,是依照檔案所使用的模式。 Resx 檔案。

<root>  
 <data name="ErrorMessage">  
  <value>There was an error completing this action. Please try again.</value>  
 </data>  
 <data name="Welcome">  
  <value>Welcome</value>  
 </data>  
</root>  

下列程式碼顯示當,翻譯的訊息可以如何傳回外掛程式來顯示訊息給使用者。 這是 Account 實體 Delete 事件之前確認階段:

protected void ExecutePreValidateAccountDelete(LocalPluginContext localContext)  
  {  
   if (localContext == null)  
   {  
    throw new ArgumentNullException("localContext");  
   }  
   int OrgLanguage = RetrieveOrganizationBaseLanguageCode(localContext.OrganizationService);  
   int UserLanguage = RetrieveUserUILanguageCode(localContext.OrganizationService,  
 localContext.PluginExecutionContext.InitiatingUserId);  
   String fallBackResourceFile = "";  
   switch (OrgLanguage)  
   {  
    case 1033:  
     fallBackResourceFile = "new_localizedStrings.en_US";  
     break;  
    case 1041:  
     fallBackResourceFile = "new_localizedStrings.ja_JP";  
     break;  
    case 1031:  
     fallBackResourceFile = "new_localizedStrings.de_DE";  
     break;  
    case 1036:  
     fallBackResourceFile = "new_localizedStrings.fr_FR";  
     break;  
    case 1034:  
     fallBackResourceFile = "new_localizedStrings.es_ES";  
     break;  
    case 1049:  
     fallBackResourceFile = "new_localizedStrings.ru_RU";  
     break;  
    default:  
     fallBackResourceFile = "new_localizedStrings.en_US";  
     break;  
   }  
   String ResourceFile = "";  
   switch (UserLanguage)  
   {  
    case 1033:  
     ResourceFile = "new_localizedStrings.en_US";  
     break;  
    case 1041:  
     ResourceFile = "new_localizedStrings.ja_JP";  
     break;  
    case 1031:  
     ResourceFile = "new_localizedStrings.de_DE";  
     break;  
    case 1036:  
     ResourceFile = "new_localizedStrings.fr_FR";  
     break;  
    case 1034:  
     ResourceFile = "new_localizedStrings.es_ES";  
     break;  
    case 1049:  
     ResourceFile = "new_localizedStrings.ru_RU";  
     break;  
    default:  
     ResourceFile = fallBackResourceFile;  
     break;  
   }  
   XmlDocument messages = RetrieveXmlWebResourceByName(localContext, ResourceFile);  
   String message = RetrieveLocalizedStringFromWebResource(localContext, messages, "ErrorMessage");  
   throw new InvalidPluginExecutionException(message);  
  }  
  protected static int RetrieveOrganizationBaseLanguageCode(IOrganizationService service)  
  {  
   QueryExpression organizationEntityQuery = new QueryExpression("organization");  
   organizationEntityQuery.ColumnSet.AddColumn("languagecode");  
   EntityCollection organizationEntities = service.RetrieveMultiple(organizationEntityQuery);  
   return (int)organizationEntities[0].Attributes["languagecode"];  
  }  
  protected static int RetrieveUserUILanguageCode(IOrganizationService service, Guid userId)  
  {  
   QueryExpression userSettingsQuery = new QueryExpression("usersettings");  
   userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");  
   userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);  
   EntityCollection userSettings = service.RetrieveMultiple(userSettingsQuery);  
   if (userSettings.Entities.Count > 0)  
   {  
    return (int)userSettings.Entities[0]["uilanguageid"];  
   }  
   return 0;  
  }  
  protected static XmlDocument RetrieveXmlWebResourceByName(LocalPluginContext context, string webresourceSchemaName)  
  {  
   context.TracingService.Trace("Begin:RetrieveXmlWebResourceByName, webresourceSchemaName={0}", webresourceSchemaName);  
   QueryExpression webresourceQuery = new QueryExpression("webresource");  
   webresourceQuery.ColumnSet.AddColumn("content");  
   webresourceQuery.Criteria.AddCondition("name", ConditionOperator.Equal, webresourceSchemaName);  
   EntityCollection webresources = context.OrganizationService.RetrieveMultiple(webresourceQuery);  
   context.TracingService.Trace("Webresources Returned from server. Count={0}", webresources.Entities.Count);  
   if (webresources.Entities.Count > 0)  
   {  
    byte[] bytes = Convert.FromBase64String((string)webresources.Entities[0]["content"]);  
    // The bytes would contain the ByteOrderMask. Encoding.UTF8.GetString() does not remove the BOM.  
    // Stream Reader auto detects the BOM and removes it on the text  
    XmlDocument document = new XmlDocument();  
    document.XmlResolver = null;  
    using (MemoryStream ms = new MemoryStream(bytes))  
    {  
     using (StreamReader sr = new StreamReader(ms))  
     {  
      document.Load(sr);  
     }  
    }  
    context.TracingService.Trace("End:RetrieveXmlWebResourceByName , webresourceSchemaName={0}", webresourceSchemaName);  
    return document;  
   }  
   else  
   {  
    context.TracingService.Trace("{0} Webresource missing. Reinstall the solution", webresourceSchemaName);  
    throw new InvalidPluginExecutionException(String.Format("Unable to locate the web resource {0}.", webresourceSchemaName));  
    return null;  
 // This line never reached  
   }  
  }  
  protected static string RetrieveLocalizedStringFromWebResource(LocalPluginContext context, XmlDocument resource, string resourceId)  
  {  
   XmlNode valueNode = resource.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, "./root/data[@name='{0}']/value", resourceId));  
   if (valueNode != null)  
   {  
    return valueNode.InnerText;  
   }  
   else  
   {  
    context.TracingService.Trace("No Node Found for {0} ", resourceId);  
    throw new InvalidPluginExecutionException(String.Format("ResourceID {0} was not found.", resourceId));  
   }  
  }  

請參閱

當地語系化產品屬性值