Как получить строку формата для указанной валюты и культуры

У меня есть отчеты SSRS, в которых отображаются суммы в валюте. Им необходимо знать как культуру, так и валюту. В некоторых отчетах в одной таблице указаны разные валюты. У меня нет проблем с культурной осведомленностью. Проблема в форматировании валюты. Важно отметить, что при экспорте в Excel значения в этих полях валют должны сортироваться как числа. Это означает, что значения ячеек должны быть числами, поэтому я не могу использовать обычные функции .ToString ("C", культура), которыми заканчиваются многие другие сообщения. Мне нужно сохранить числовое значение в поле и применить строку формата .NET к числу (например, «'$' #, 0.00; ('$' #, 0.00)»). Таким образом, Excel будет обрабатывать значение как число для целей сортировки, но отображать валюту в правильном формате.

Можно ли использовать код для изменения экземпляра NumberFormatInfo, а затем каким-то образом вернуть строковое значение средства форматирования, например «'€' #, 0.00; ('€' #, 0.00)»?

var numberFormat = new CultureInfo("en-US").NumberFormat;
numberFormat.CurrencySymbol = "€";
return numberFormat.GetCurrencyFormatString(); //this is an imaginary function that I need to return "'€'#,0.00;('€'#,0.00)"

Я попытался программно установить символ валюты на основе информации о валюте каждой строки. Насколько мне известно, SSRS не позволяет мне использовать Expression для установки символа валюты. Он предлагает только раскрывающийся список.

Моим пользователям не нравится, когда я показываю код валюты (например, USD, CAD), поэтому я застрял с отображением символа (например, $, CA $).


person user2005169    schedule 24.10.2019    source источник
comment
вот несколько подсказок. stackoverflow.com/questions/6924067 /. Если вы хотите экспортировать его в Excel, форматирование не требуется. Excel будет лучше понимать неформатированные числа и будет применять собственное форматирование.   -  person Holger    schedule 24.10.2019
comment
Спасибо за ответ, Хольгер. Но ответ в этом сообщении рекомендует использовать функцию String.Format (), которая вернет строку. Если я использую строку в ячейке, Excel отсортирует ее как строку. Также одно из моих требований - отображать разные валюты в одной таблице. Excel не может знать, какой символ валюты применить, пока я не скажу, какой использовать. Вот почему мне нужна строка формата - потому что Excel ее понимает.   -  person user2005169    schedule 24.10.2019
comment
Вы просили форматирование, конечно вы получите строку, что-то еще не форматируется. Что порекомендовать, зависит от того, как вы пытаетесь перенести что-либо в excel - через буфер обмена; это скорее всего текст. Через Interop вы можете передать своего двойника напрямую. С помощью функции «Копировать и вставить» Excel будет анализировать входящий текст настолько хорошо, насколько это возможно, я не думаю, что он распознает более одного символа в качестве валюты и не распознает какие-либо другие единицы. И как запасной вариант, если он не может быть проанализирован, он остается строкой. Таким образом, чем больше вы форматируете число, тем более вероятно, что оно останется строкой.   -  person Holger    schedule 25.10.2019
comment
Я конкретно говорю здесь о SSRS. При экспорте SSRS в Excel значение в ячейке должно быть числом. Форматирование числа - вот что мне нужно. Если я применю к числу формат '$' #, 0.00; ('$' #, 0.00), Excel все равно будет знать, что это число, и это прекрасно. И он отформатирует число как сумму в долларах. Я ищу функцию, которая дает мне что-то вроде '$' #, 0.00; ('$' #, 0.00), которая уважает правильный символ валюты, а также текущие настройки культуры, которые влияют на то, где отображаются символы валюты (либо до или после числа)   -  person user2005169    schedule 26.10.2019
comment
Пока вы не поясняете, что вы имеете в виду под экспортом, это обсуждение бесполезно. Вы можете использовать Interop-Api, вы можете использовать буфер обмена, вы можете использовать буфер обмена как в виде обычного текста, так и в формате html, вы можете сохранять как xlsx-файлы, вообще не связываясь с Excel.   -  person Holger    schedule 26.10.2019
comment
Я имею в виду встроенную функцию SSRS для автоматического преобразования отчетов в формат Excel.   -  person user2005169    schedule 28.10.2019


Ответы (1)


Насколько я могу судить, вам нужно будет вручную создать эту строку формата, используя класс CultureInfo.

Использование документации по CurrencyPositivePattern и CurrencyNegativePattern (см. здесь и здесь), я собрал кое-что, что работает, но, возможно, потребуется дополнительная настройка:

string GetCurrencyFormat(CultureInfo culture)
{            
    //we'll use string.Format later to replace {0} with the currency symbol
    //and {1} with the number format
    string[] negativePatternStrings = { "({0}{1})", "-{0}{1}", "{0}-{1}", "{0}{1}-", "({1}{0})",
                            "-{1}{0}", "{1}-{0}", "{1}{0}-", "-{1} {0}", "-{0} {1}",
                            "{1} {0}-", "{0} {1}-", "{0} -{1}", "{1}- {0}", "({0} {1})",
                            "({1} {0})" };
    string[] positivePatternStrings = { "{0}{1}", "{1}{0}", "{0} {1}", "{1}{0}" };

    var numberFormat = culture.NumberFormat;

    //Generate 0's to fill in the format after the decimal place
    var decimalPlaces = new string('0', numberFormat.CurrencyDecimalDigits);

    //concatenate the full number format, e.g. #,0.00
    var fullDigitFormat = $"#{numberFormat.CurrencyGroupSeparator}0{numberFormat.CurrencyDecimalSeparator}{decimalPlaces}";

    //use string.Format on the patterns to get the positive and 
    //negative formats
    var positiveFormat = string.Format(positivePatternStrings[numberFormat.CurrencyPositivePattern],  
                                       numberFormat.CurrencySymbol, fullDigitFormat);
    var negativeFormat = string.Format(negativePatternStrings[numberFormat.CurrencyNegativePattern], 
                                       numberFormat.CurrencySymbol, fullDigitFormat);

    //finally, return the full format
    return $"{positiveFormat};{negativeFormat}";
}

Это возвращает, например, $#,0.00;($#,0.00) для en-US, £#,0.00;-£#,0.00 для en-GB.

person KMoussa    schedule 24.10.2019
comment
Спасибо KMoussa. Это очень близко к тому, что я хочу. Кажется, это хорошо работает для валют, где символ стоит перед числом. Но некоторые культурные форматы требуют символа валюты после числа, например: #, 0 'CA $'; (#, 0 'CA $'). Я надеялся, что у .NET будет способ просто вернуть то, что он использует (учитывая культуру), но похоже, что мне придется сделать что-то подобное, чтобы выполнить свою работу! - person user2005169; 26.10.2019
comment
Я уверен, что есть и другие специфические особенности культуры, о которых я тоже не подозреваю, а не только положение символа валюты. Вот почему я надеялся, что фреймворк (который знает об этих нюансах, учитывая культуру) выдаст строку формата, которую он использует. - person user2005169; 26.10.2019