Module Module1
Sub main()
Dim pl(), pll() As Integer
Dim a, b As Integer
ReDim pl(0)
ReDim pll(0)
Do
a = InputBox("insert number:")
If a <> 0 Then
b = b + 1
ReDim Preserve pl(b)
pl(b) = a
End If
Loop Until a = 0
pll = **se(pl)**
End Sub
Function se(pol()) As Integer()
Dim r, t, w, m As Integer
Dim fix() As Integer
ReDim fix(0)
r = UBound(pol)
w = 2
For t = 1 To r
For m = 1 To r
If w <= r Then
If pol(w) < pol(t) Then
ReDim Preserve fix(t)
fix(t) = pol(w)
End If
End If
w = w + 1
Next
Next
se = fix
End Function
终端模块
嗨,我创建了这个函数(不知道它是否有效(se(pl(,它接受数字数组并返回该数组,但按升序排列。但是当我想将该函数分配给数组 - pll=se(pl( 时,它会给我这个错误 ==>"整数类型的值无法转换为对象,因为整数不是引用类型">
对不起,我是菜鸟,有人可以帮忙吗?
我调整了你的代码以使其工作。然而,我试图尽可能多地坚持原始代码,以便您更容易从此解决方案中学习:
Option Base 0
Option Explicit
Sub main()
Dim pl() As Integer
Dim a As Integer, b As Integer
ReDim pl(0)
Do
a = InputBox("insert number:")
If IsNumeric(a) And a <> 0 Then
b = b + 1
ReDim Preserve pl(b)
pl(b) = a
End If
Loop Until a = vbNullString
Debug.Print "Unsorted:"
For a = LBound(pl) To UBound(pl)
Debug.Print pl(a)
Next a
se intArray:=pl
Debug.Print "Sorted:"
For a = LBound(pl) To UBound(pl)
Debug.Print pl(a)
Next a
End Sub
Function se(ByRef intArray() As Integer)
Dim t As Integer, w As Integer, m As Integer
For t = LBound(intArray) To UBound(intArray)
For m = LBound(intArray) To UBound(intArray)
If intArray(t) < intArray(m) Then
w = intArray(t)
intArray(t) = intArray(m)
intArray(m) = w
End If
Next m
Next t
End Function
一些重要注意事项:
(1(如果要在一行中Dim
多个变量,则必须为每个变量重复DataType
。所以,它是Dim a as Integer, b as Integer
而不是Dim a, b as Integer
.在这两种情况下的后一种情况下,a
将是DataType
变体(而不是可能预期的Integer
(。
(2(要将VBA中的arrays
从过程传递到函数,您必须将其传递ByRef
。因此,无需创建第二个或第三个array
(例如 pll()
或 fix()
(。
(3(有一个VBA命令Fix
。因此,您不能将其用于变量。
让我知道上述内容是否有帮助,或者您是否需要更多的背景或轻微的调整。
您同时标记了"VBA"和"Visual Studio",但以下内容仅适用于VBA
至于你的代码,我只是通过用fixed
替换fix
来让它工作(意味着它运行到最后没有错误(,因为我的 Excel VBA"编译器"抛出"语法错误"消息由于存在"FIX(("VBA 函数。
因此,在该替换之后,调用了Function se
,并且它返回了一个没有问题的整数数组。
但它没有按照您所说的应有的方式进行操作,即:"按升序返回传递的数组"。
此外,变量声明和输入过程都允许传递字符串。
所以这里遵循我的建议,让你的代码做你所说的你需要的("按升序返回传递的数组"(,使用更健壮的输入过程
Option Explicit
Sub main()
Dim pl() As Integer, pll() As Integer
pl = TryConvertToInt(Split(InputBox("insert numbers (separated by space):")))
pll = se(pl)
End Sub
Function TryConvertToInt(arr As Variant) As Integer()
Dim i As Long, n As Long
ReDim myint(1 To UBound(arr) - LBound(arr) + 1) As Integer
For i = LBound(arr) To UBound(arr)
If IsNumeric(arr(i)) And arr(i) <> 0 Then
n = n + 1
myint(n) = CInt(arr(i))
End If
Next i
ReDim Preserve myint(1 To n) As Integer
TryConvertToInt = myint
End Function
Function se(pol() As Integer) As Integer()
'adapted from https://support.microsoft.com/en-us/kb/133135
Dim Temp As Integer
Dim i As Integer
Dim NoExchanges As Boolean
Dim fixed() As Integer
ReDim fixed(1 To UBound(pol) - LBound(pol) + 1)
fixed = pol
' Loop until no more "exchanges" are made.
Do
NoExchanges = True
' Loop through each element in the array.
' For i = 1 To UBound(pol) - 1
For i = LBound(fixed) To UBound(fixed) - 1
' If the element is greater than the element following it, exchange the two elements.
If fixed(i) > fixed(i + 1) Then
NoExchanges = False
Temp = fixed(i)
fixed(i) = fixed(i + 1)
fixed(i + 1) = Temp
End If
Next i
Loop While Not (NoExchanges)
se = fixed
End Function
如您所见:
main
sub 现在非常简单,减少到三个语句- 第一个是变量声明一
第二个语句嵌套了三个调用:
- 调用
InpuBox
函数,其中要求用户输入所有用空格分隔的所需数字(并且不需要用零来关闭序列( - 调用
Split
函数,让它将输入字符串解析为一个字符串数组,该数组由与用空格分隔的输入字符串一样多的字符串组成 - 调用
TryConvertToInt
函数,负责分析字符串数组并将其转换为整数数组,只允许零以外的数字
- 调用
第三条语句调用
se
函数并将其返回整数数组放入整数数组pll
se
函数具有派生自 https://support.microsoft.com/en-us/kb/133135 的排序算法,仅适用于处理整数数组。
有了这样的结构,你现在可以更有效地编码,因为你可以通过调用特定的子和/或函数来专注于main
子做"主要"工作(做这个,做那个,...(。
这让"非主"工作到特定的子或函数中,只为特定目的而集中精力:例如,您可能希望自定义TryConvertToInt
函数以进行更详细的过滤操作