配列をソートするか、Filesystemオブジェクトフォルダのファイルを、人間がソートした場合の予想通りに並べ替えたい。私が最終的に成し遂げようとしているのは、フォルダから画像を取り込んで、それが何を表しているかを識別するために、それぞれの上にテキストで単語文書に挿入するマクロです。ここではガイドのステップを使用します。 100;Word VBAナチュラルソート
テストサブをセットアップします。
Sub RunTheSortMacro()
Dim i As Long
Dim myArray As Variant
'Set the array
myArray = Array("Step-1", "Step-2", "Step-10", "Step-15", "Step-9", "Step-20", "Step-100", "Step-8", "Step-7")
'myArray variable set to the result of SortArray function
myArray = SortArray(myArray)
'Output the Array through a message box
For i = LBound(myArray) To UBound(myArray)
MsgBox myArray(i)
Next i
End Sub
私が見つけた唯一のベストソート機能は、実際には数字にのみ有効です。
Function SortArray(ArrayIn As Variant)
Dim i As Long
Dim j As Long
Dim Temp
'Sort the Array A-Z
For i = LBound(ArrayIn) To UBound(ArrayIn)
For j = i + 1 To UBound(ArrayIn)
If ArrayIn(i) > ArrayIn(j) Then
SrtTemp = ArrayIn(j)
ArrayIn(j) = ArrayIn(i)
ArrayIn(i) = SrtTemp
End If
Next j
Next i
SortArray = ArrayIn
End Function
この関数は配列を次のように返します。 ステップ-1、 ステップ-10、 ステップ100、 ステップ-15、 ステップ-2、 STEP-20、 ステップ-7、 ステップ-8、 ステップ9
私欲しいです; ステップ-1、 ステップ-2、 ステップ-7、 ステップ-8、 ステップ-9、 ステップ-10、 ステップ-15、 STEP-20、 ステップ100
思っStrComp(ArrayIn(i)、ArrayIn(j)、vbBinaryCompare/vbTextCompare)を使用すると、同じ方法で並べ替えるように見えます。それが簡単な場合は、入力ファイルを並べ替える方法が見つからなかったので、私は配列ルートだけを行っています。
Set objFSO = CreateObject("Scripting.Filesystemobject")
Set Folder = objFSO.GetFolder(FolderPath)
For Each image In Folder.Files
ImagePath = image.Path
Selection.TypeText Text:=Left(image.Name, Len(image.Name) - 4)
Selection.TypeText Text:=vbCr
'Insert the images into the word document
Application.Selection.EndKey END_OF_STORY, MOVE_SELECTION
Application.Selection.InlineShapes.AddPicture (ImagePath)
Application.Selection.InsertBreak 'Insert a pagebreak
Next
私は自然に並べ替えることができる2つの配列にファイル名とパスを分割します。
Set objFiles = Folder.Files
FileCount = objFiles.Count
ReDim imageNameArray(FileCount)
ReDim imagePathArray(FileCount)
icounter = 0
For Each image In Folder.Files
imageNameArray(icounter) = (image.Name)
imagePathArray(icounter) = (image.Path)
icounter = icounter + 1
Next
しかし、VBAでは自然な並べ替えの参照が見つかりません。
アップデート、追加情報;
私は数字の後にAとBは考えていませんでした。私が検索したすべてのものは、 "自然な並べ替え"に同意しています。 1,2,3、A、B、C; Apple < 1A < 1C < 2.正規表現は良いかもしれません これは私がpythonスクリプトでこれを達成した方法でした。
import os
import re
def tryint(s):
try:
return int(s)
except:
return s
def alphanum_key(s):
""" Turn a string into a list of string and number chunks.
"z23a" -> ["z", 23, "a"]
"""
return [ tryint(c) for c in re.split('([0-9]+)', s) ]
def sort_nicely(l):
""" Sort the given list in the way that humans expect.
"""
l.sort(key=alphanum_key)
files = [file for file in os.listdir(".") if (file.lower().endswith('.png')) or (file.lower().endswith('.jpg'))]
files.sort(key=alphanum_key)
for file in sorted(files,key=alphanum_key):
stepname = file.strip('.jpg')
print(stepname.strip('.png')
私はこれらを発見しました。
Function SortArray(ArrayIn As Variant)
Dim i As Long
Dim j As Long
Dim Temp1 As String
Dim Temp2 As String
Dim Temp3 As String
Dim Temp4 As String
'Sort the Array A-Z
For i = LBound(ArrayIn) To UBound(ArrayIn)
For j = i + 1 To UBound(ArrayIn)
Temp1 = ArrayIn(i)
Temp2 = ArrayIn(j)
Temp3 = onlyDigits(Temp1)
Temp4 = onlyDigits(Temp2)
If Val(Temp3) > Val(Temp4) Then
ArrayIn(j) = Temp1
ArrayIn(i) = Temp2
End If
Next j
Next i
SortArray = ArrayIn
End Function
Function onlyDigits(s As String) As String
' Variables needed (remember to use "option explicit"). '
Dim retval As String ' This is the return string. '
Dim i As Integer ' Counter for character position. '
' Initialise return string to empty '
retval = ""
' For every character in input string, copy digits to '
' return string. '
For i = 1 To Len(s)
If Mid(s, i, 1) >= "0" And Mid(s, i, 1) <= "9" Then
retval = retval + Mid(s, i, 1)
End If
Next
' Then return the return string. '
onlyDigits = retval
End Function
アルファベット順ではない数値の並べ替えを入力してください.1Bは1Aの前にソートされています。
あなたは 'が含まれている一時変数を直接配列エントリを比較するのではなく2なかった場合、それは十分です(ArrayIn(i)、 "Step-"、 "") 'およびReplace(ArrayIn(j)、" Step- "、" ")'を使用します。次に、あなたの望む結果にあなたを残すはずの数字だけを比較しています。 – LocEngineer
私はそれがより一般的であることを望んでいます、 "ステップ"は私のイメージが現在ラベル付けされている方法ですが、それらは "ステップ"でも数字の後ろに文字を含むことさえできます。ステップ7a。 –
次に、いくつかのバリアントをカバーするための例を提供する必要があります。また、これらのバリアントが関与する「自然なソート」を検討する必要があります。たぶんRegexが助けることができます。 – LocEngineer