2015-11-15 2 views
0

Я пытаюсь преобразовать столбец в лист Excel в поплавок в моем приложении F #. Проблема в том, что я не знаю, в каком формате предоставляется валюта. Это можно ввести вручную, с символом или без него, и, конечно же,. и символы всегда беспорядок.F # Преобразование валюты из Excel

Есть ли какой-нибудь «короткий и сладкий» способ ведения чего-либо, что, по-видимому, представляет собой совокупность возможностей для фактического значения с плавающей запятой, которое позже после того, как некоторая арифметика может быть напечатана как валюта?

Побочная проблема я столкнулся: Когда столбец в Excel отмечен как номер 600,00 будет экспортироваться через библиотеку для взаимодействия с другой как 600; 534.20 будет экспортироваться как 534.2 Простой синтаксический разбор. символа недостаточно.

Символ, который не показан, будет экспортироваться через библиотеки interop в виде ? (с последующим пробелом).

Эти варианты не приста:

let ParseFloat1 (o:obj) = 
    float (o.ToString()) 


let parseFloat2 (o:obj) = 
    float (System.Single.Parse(o.ToString())) 

После этих попыток я просто сходила с ума и начал russamafuzzin' решения, даже не этот дракон плохая идея работала:

let ParseFloat o = 
    // ugly 
    let mutable _string = o.ToString() 

    // because of the weird "lets leave trailing zero's off behavior 
    let changeString (s:string) = 
     match s.LastIndexOf "." with 
     | 0 | -1 -> s + "00" 
     | 1 -> s + "0" 
     | _ -> s 

    _string <- changeString _string 

    let characters = _string.ToCharArray() 
    // remove all the non numbers from the string 
    let rec parse source dest = 
     match source with 
     | h::t -> 
        match h with 
        | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' -> parse t (dest + h.ToString()) 
        | _ -> parse t dest 
     | _ -> dest 

    let _float = parse (Array.toList characters) "" 
    let result = (float (System.Single.Parse(_float)))/(float 100) 
    result 

I действительно надеюсь, что кто-то может мне помочь, потому что это сводит меня с ума. Заранее спасибо.

EDIT (16-11-2015):

Более подробную информацию после того, как действительные комментарии, я ценю помощь и комментарии.

Я перепутал проблему с более «частями», поэтому я представил несколько соглашений для этого приложения. Я понял, что это не решение для этой проблемы, так что я не нужно положить в некоторых ограничениях и надеяться на лучший ...

  • Я получаю десятичный символ из CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator и убедитесь, что столбец лист Excel имеет введите Number, добавив столбец этого типа и, если необходимо, перепродайте.
  • Я удаляю все остальные символы из строки, оставляя только разделитель на месте. (Точно так же, как ответ Петр)
  • Выполнение Excel в том же контексте и приложением, гарантируя, что CultureInfo - это то же самое.

Чтобы расширить ответ Пети:

let ParseFloat o = 
    let decimalSeparator = Convert.ToChar(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator); 
    let newv = String((o.ToString()) |> Seq.filter (fun c -> Char.IsNumber c || c = decimalSeparator) |> Array.ofSeq) 
    let rslt = match Double.TryParse(newv) with 
       | true, number -> (float number) 
       | false, _ -> throw "Cannot parse the number" 
    rslt 
+1

Вы можете использовать перегрузку Double.TryParse() с различными комбинациями NumberStyles и Cultures: https://msdn.microsoft.com/en-us/library/3s27fasw(v=vs.110).aspx – Petr

+0

Я не знаю формат заранее. Более того, я не знаю формат на каждом листе. Вот почему я ищу действительно общий «всегда» рабочий метод –

+2

В этом случае, вероятно, нет «всегда» рабочего решения. В некоторых культурах ',' может быть тысяча разделителей, а в других - десятичной точкой. И если номер написан с использованием китайских цифр? – Petr

ответ

1

Что-то вроде этого?

open System 
let value = "£1,097." 
let newv = String(value |> Seq.filter (fun c -> Char.IsNumber c || c = '.') |> Array.ofSeq) 
let rslt = match Double.TryParse(newv) with 
      | true, number -> printfn"Converted '%s' to %.2f" value number 
      | false, _ -> printfn "Unable to convert '%s'" value 

Результат:

Старинное '£ 1097. до 1097,00

+0

Это замечательно! Работает как очарование, я просто «своп». для a, когда там он работает в другой культуре. Большое спасибо и в качестве примечания, отличный код; обертывание этой трубы в ctor, никогда бы не пробовал это. –

Смежные вопросы