F# 从 Excel 转换货币
F# Converting Currency from Excel
我正在尝试将 Excel sheet 中的列转换为 F# 应用程序中的浮点数。问题是我不知道提供货币的格式。这可以手动输入,带或不带符号,当然还有 .而且,符号总是一团糟
是否有任何 "short and sweet" 方法可以将看似不连贯的可能性数组转换为实际浮点值,经过一些算术运算后可以将其打印为货币?
我遇到的一个附带问题:
当 Excel 中的列标记为 Number 时,600.00 将通过互操作库导出为 600; 534.20 将导出为 534.2
上的简单解析。符号是不够的。
未显示的符号 Excel 将通过互操作库导出为 ?(后跟 space)。
这些选项不起作用:
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
我真的希望有人能帮助我,因为这让我发疯。提前谢谢你。
编辑 (16-11-2015):
有效评论后的更多信息,我感谢所有的帮助和评论。
我已将问题分解为更多 "parts" 因此我为该应用程序介绍了一些约定。我认为这个问题没有解决方案,所以我需要设置一些限制并希望最好...
- 我从
CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
中获取小数点符号,并确保 excel sheet 中的列是 Number 类型,添加此类型的列并在需要时重新保存。
- 我从字符串中删除了所有其他符号,只留下分隔符。 (就像彼得的回答一样)
- 运行 Excel 在相同的上下文和应用程序中确保
CultureInfo
相同。
扩展 Petr 的回答:
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
是这样的吗?
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
结果:
Converted '£1,097.' to 1097.00
我正在尝试将 Excel sheet 中的列转换为 F# 应用程序中的浮点数。问题是我不知道提供货币的格式。这可以手动输入,带或不带符号,当然还有 .而且,符号总是一团糟
是否有任何 "short and sweet" 方法可以将看似不连贯的可能性数组转换为实际浮点值,经过一些算术运算后可以将其打印为货币?
我遇到的一个附带问题: 当 Excel 中的列标记为 Number 时,600.00 将通过互操作库导出为 600; 534.20 将导出为 534.2 上的简单解析。符号是不够的。
未显示的符号 Excel 将通过互操作库导出为 ?(后跟 space)。
这些选项不起作用:
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
我真的希望有人能帮助我,因为这让我发疯。提前谢谢你。
编辑 (16-11-2015):
有效评论后的更多信息,我感谢所有的帮助和评论。
我已将问题分解为更多 "parts" 因此我为该应用程序介绍了一些约定。我认为这个问题没有解决方案,所以我需要设置一些限制并希望最好...
- 我从
CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
中获取小数点符号,并确保 excel sheet 中的列是 Number 类型,添加此类型的列并在需要时重新保存。 - 我从字符串中删除了所有其他符号,只留下分隔符。 (就像彼得的回答一样)
- 运行 Excel 在相同的上下文和应用程序中确保
CultureInfo
相同。
扩展 Petr 的回答:
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
是这样的吗?
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
结果:
Converted '£1,097.' to 1097.00