如何将以分数形式书写的一般数据转换为 3 位小数。替换“0”。和 ”。”
How to turn general data written as fractions into 3 place decimal numbers. Replace " 0." with "."
我正在尝试将以 3/4" 或 13 7/32" 等分数表示的一般数据转换为 3 位小数,例如 0.750 或 13.219。
我有一个有效的 table 替代品,可以处理 0 到 1" 的分数。它不能处理像 13 7/32" 这样的带分数。它留给我 13 0.219,这就是我需要替换“0”的原因。和 ”。”将 13 和 219 连在一起并加上一个小数点。
我们分多个步骤进行此数据转换并手动输入,因为 Excel 尝试将一些分数(如 3/4")转换为日期。
原始数据
结果数据
Sub FractionConvertMTO()
'this section works
For i = 6 To 70
Worksheets("BOM").Range("F6:H48").Select
Selection.Replace what:=Cells(i, 21).Value, Replacement:=Cells(i, 22).Value, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False
Next
'this section doesn't work
For i = 6 To 70
Worksheets("BOM").Range("F6:H48").Select
str1 = " "
str1 = Trim(Replace(str1, " ", "+"))
Next
'this section changes the format.
For i = 66 To 130
Range("F6:H48").NumberFormat = "0.000"
Next
'this section is supposed to add an = sign in front of the cell contents but doesn't work.
Dim Cell As Range
For Each Cell In Range("F6:H48")
Cell.Value = "=" & Cell.Value
Next Cell
'this section works to highlight the first cell
Worksheets("BOM").Cells(1, 1).Select
End Sub
str1 = trim(替换(str1, "0.", "."))
如果处理较新的动态数组功能(vers. 2019+,MS365),您可能会一次性将结果写入整个原始范围(目标范围),如下所示(覆盖现有范围;否则定义一个给定的偏移量来标识另一个目标范围:rng.Offset(,n)=..
).
提示:在测试之前制作备份副本(因为它会覆盖 rng
)!
请注意,此示例假定 "
字符(asc 值为 34)。
A) 首先尝试通过表格 VALUE()
公式求值
警告:通过 VALUE()
转换空白将写成 #VALUE!
结果,这需要进一步循环。为避免这种情况,您可以在公式 myFormula = "=VALUE(SUBSTITUTE(" & """0""&" & rng.Address & ","""""""",""""))" so that results would be displayed as zero.
前加一个零
Sub ChangeToFractionValues()
'1) define original range to be replaced
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("BOM").Range("F6:H48")
'2) define tabular formula
Dim myFormula As String
'myFormula = "=VALUE(SUBSTITUTE(" & rng.Address & ","""""""",""""))"
'Alternative to avoid #VALUE! displays for blanks:
myFormula = "=VALUE(SUBSTITUTE(" & """0""&" & rng.Address & ","""""""",""""))"
'Debug.Print myFormula
'3) overwrite original range (otherwise code an offset rng.Offset(,n).Value = ...
rng.Value2 = rng.Parent.Evaluate(myFormula)
End Sub
根据评论得出结论:
虽然速度很快,但这种方法有一个很大的缺点:Excel 解释 date-like 数字,通过 [=56= 在内部将它们转换为日期] 在此处输入数字部分,因此 3/4"
的单元格输入将 return 对应的当年 3 月 4 日的日期值。
B) 基于循环中直接单元格计算的重写代码 //编辑
与上述处理类似,此方法也基于评估,但将所有 公式 收集为变体数据字段数组 v
中的字符串,这允许操作和单独评估每个单元格输入:
Sub ChangeToFractionValues()
'1) define original range to be replaced
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("BOM").Range("F6:H48")
'2) assign formula strings to variant 1-based 2-dim data field array
Dim v As Variant
v = rng.Formula2
'3) evaluate results in a loop
Dim i As Long, j As Long
For i = 1 To UBound(v)
For j = 1 To UBound(v, 2)
v(i, j) = Evaluate("0" & Replace(v(i, j), Chr(34), ""))
Next j
Next i
'4) overwrite original range (otherwise code an offset rng.Offset(,n).Value = ...
rng.Value = v
End Sub
我从我的有用函数库中挖出了以下方法。它将表示为小数字符串的数字转换为等效的数字。只需循环遍历需要转换的单元格并调用此方法:
Public Function FractionToNumber(ByVal Value As String, Optional ByVal Digits As Long = 0) As Double
Dim P As Integer
Dim N As Double
Dim Num As Double
Dim Den As Double
Value = Trim$(Value)
P = InStr(Value, "/")
If P = 0 Then
N = Val(Value)
Else
Den = Val(Mid$(Value, P + 1))
Value = Trim$(Left$(Value, P - 1))
P = InStr(Value, " ")
If P = 0 Then
Num = Val(Value)
Else
Num = Val(Mid$(Value, P + 1))
N = Val(Left$(Value, P - 1))
End If
End If
If Den <> 0 Then N = N + Num / Den
FractionToNumber = Round(N, Digits)
End Function
您也可以编写如下代码:
Sub FractionConvertMTO()
Dim rng As Range
Dim Arr As Variant
Arr = Worksheets("MTO").Range("F6:H48")
For Row = 1 To UBound(Arr, 1)
For col = 1 To UBound(Arr, 2)
str1 = Arr(Row, col)
pos1 = InStr(str1, " ")
pos2 = InStr(str1, "/")
If pos2 = 0 Then
N = val(str1)
Num = 0: Den = 1
Else
If pos1 And pos1 < pos2 Then
N = val(Left$(str1, pos1 - 1))
Num = val(Mid$(str1, pos1 + 1))
Else
N = 0
Num = val(Left$(str1, pos2 - 1))
End If
Den = val(Mid$(str1, pos2 + 1))
End If
Arr(Row, col) = N + Num / Den
Next col
Next Row
Worksheets("MTO").Range("F6", "H48") = Arr
End Sub
我正在尝试将以 3/4" 或 13 7/32" 等分数表示的一般数据转换为 3 位小数,例如 0.750 或 13.219。
我有一个有效的 table 替代品,可以处理 0 到 1" 的分数。它不能处理像 13 7/32" 这样的带分数。它留给我 13 0.219,这就是我需要替换“0”的原因。和 ”。”将 13 和 219 连在一起并加上一个小数点。
我们分多个步骤进行此数据转换并手动输入,因为 Excel 尝试将一些分数(如 3/4")转换为日期。
原始数据
结果数据
Sub FractionConvertMTO()
'this section works
For i = 6 To 70
Worksheets("BOM").Range("F6:H48").Select
Selection.Replace what:=Cells(i, 21).Value, Replacement:=Cells(i, 22).Value, _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False
Next
'this section doesn't work
For i = 6 To 70
Worksheets("BOM").Range("F6:H48").Select
str1 = " "
str1 = Trim(Replace(str1, " ", "+"))
Next
'this section changes the format.
For i = 66 To 130
Range("F6:H48").NumberFormat = "0.000"
Next
'this section is supposed to add an = sign in front of the cell contents but doesn't work.
Dim Cell As Range
For Each Cell In Range("F6:H48")
Cell.Value = "=" & Cell.Value
Next Cell
'this section works to highlight the first cell
Worksheets("BOM").Cells(1, 1).Select
End Sub
str1 = trim(替换(str1, "0.", "."))
如果处理较新的动态数组功能(vers. 2019+,MS365),您可能会一次性将结果写入整个原始范围(目标范围),如下所示(覆盖现有范围;否则定义一个给定的偏移量来标识另一个目标范围:rng.Offset(,n)=..
).
提示:在测试之前制作备份副本(因为它会覆盖 rng
)!
请注意,此示例假定 "
字符(asc 值为 34)。
A) 首先尝试通过表格 VALUE()
公式求值
警告:通过 VALUE()
转换空白将写成 #VALUE!
结果,这需要进一步循环。为避免这种情况,您可以在公式 myFormula = "=VALUE(SUBSTITUTE(" & """0""&" & rng.Address & ","""""""",""""))" so that results would be displayed as zero.
Sub ChangeToFractionValues()
'1) define original range to be replaced
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("BOM").Range("F6:H48")
'2) define tabular formula
Dim myFormula As String
'myFormula = "=VALUE(SUBSTITUTE(" & rng.Address & ","""""""",""""))"
'Alternative to avoid #VALUE! displays for blanks:
myFormula = "=VALUE(SUBSTITUTE(" & """0""&" & rng.Address & ","""""""",""""))"
'Debug.Print myFormula
'3) overwrite original range (otherwise code an offset rng.Offset(,n).Value = ...
rng.Value2 = rng.Parent.Evaluate(myFormula)
End Sub
根据评论得出结论:
虽然速度很快,但这种方法有一个很大的缺点:Excel 解释 date-like 数字,通过 [=56= 在内部将它们转换为日期] 在此处输入数字部分,因此 3/4"
的单元格输入将 return 对应的当年 3 月 4 日的日期值。
B) 基于循环中直接单元格计算的重写代码 //编辑
与上述处理类似,此方法也基于评估,但将所有 公式 收集为变体数据字段数组 v
中的字符串,这允许操作和单独评估每个单元格输入:
Sub ChangeToFractionValues()
'1) define original range to be replaced
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("BOM").Range("F6:H48")
'2) assign formula strings to variant 1-based 2-dim data field array
Dim v As Variant
v = rng.Formula2
'3) evaluate results in a loop
Dim i As Long, j As Long
For i = 1 To UBound(v)
For j = 1 To UBound(v, 2)
v(i, j) = Evaluate("0" & Replace(v(i, j), Chr(34), ""))
Next j
Next i
'4) overwrite original range (otherwise code an offset rng.Offset(,n).Value = ...
rng.Value = v
End Sub
我从我的有用函数库中挖出了以下方法。它将表示为小数字符串的数字转换为等效的数字。只需循环遍历需要转换的单元格并调用此方法:
Public Function FractionToNumber(ByVal Value As String, Optional ByVal Digits As Long = 0) As Double
Dim P As Integer
Dim N As Double
Dim Num As Double
Dim Den As Double
Value = Trim$(Value)
P = InStr(Value, "/")
If P = 0 Then
N = Val(Value)
Else
Den = Val(Mid$(Value, P + 1))
Value = Trim$(Left$(Value, P - 1))
P = InStr(Value, " ")
If P = 0 Then
Num = Val(Value)
Else
Num = Val(Mid$(Value, P + 1))
N = Val(Left$(Value, P - 1))
End If
End If
If Den <> 0 Then N = N + Num / Den
FractionToNumber = Round(N, Digits)
End Function
您也可以编写如下代码:
Sub FractionConvertMTO()
Dim rng As Range
Dim Arr As Variant
Arr = Worksheets("MTO").Range("F6:H48")
For Row = 1 To UBound(Arr, 1)
For col = 1 To UBound(Arr, 2)
str1 = Arr(Row, col)
pos1 = InStr(str1, " ")
pos2 = InStr(str1, "/")
If pos2 = 0 Then
N = val(str1)
Num = 0: Den = 1
Else
If pos1 And pos1 < pos2 Then
N = val(Left$(str1, pos1 - 1))
Num = val(Mid$(str1, pos1 + 1))
Else
N = 0
Num = val(Left$(str1, pos2 - 1))
End If
Den = val(Mid$(str1, pos2 + 1))
End If
Arr(Row, col) = N + Num / Den
Next col
Next Row
Worksheets("MTO").Range("F6", "H48") = Arr
End Sub