2016-05-23 203 views
1

請參閱底部以獲取從答案中使用的替換代碼。使用VBA從文件名中提取可變長度字符串

我正在處理一個電子表格,它從目錄中的文件列表中提取名稱。這些文件被命名爲John Doe 01011980.xlsxJaney B Deer 02031983.xlsx,因此名字和姓氏的長度可變,可以但不總是包含中間首字母,然後是簡化的出生日期。這是我目前使用的代碼(不起作用)將文件名稱中的名稱排序。

Private Sub nextname_Click() 

Dim strDir As String, first As String, last As String, dateofbirth As String, check As String 

strDir = Worksheets("Sheet1").Range("A1").Text 
strDir = Dir 
If strDir = "" Then 
    Unload Me 
    MsgBox ("I couldn't find any other client files by that name.") 
    Exit Sub 
End If 

check = Left(strDir, InStr(1, strDir, ".xlsx", vbTextCompare) - 10) 

''THE ISSUE IS CONTAINED HEREIN 
If InStr(1, check, " * ", vbTextCompare) > 0 Then 
    first = Trim(Left(check, Len(check) - InStr(1, check, " ", vbTextCompare) - 2)) 
    last = Trim(Right(check, Len(check) - InStr(1, check, " ", vbTextCompare) - 2)) 
Else 
    first = Trim(Left(check, Len(check) - InStr(1, check, " ", vbTextCompare))) 
    last = Trim(Right(check, Len(check) - InStr(1, check, " ", vbTextCompare))) 
End If 
''END ISSUE 

dateofbirth = mid(strDir, Len(strDir) - 12, 2) & "/" & mid(strDir, Len(strDir) - 10, 2) & "/" & mid(strDir, Len(strDir) - 8, 4) 

Worksheets("Sheet1").Range("A1") = "C:\filepath\" & strDir 

reviewNameUserform.first_Text.Text = first 
reviewNameUserform.last_Text.Text = last 
reviewNameUserform.dob_Text.Text = dateofbirth 

如上面標明是在拉出第一和最後一個名字的文件名,最特別是當有一箇中間的初始問題。目前,它僅使用Else語句來顯示JohnDoeJaney BB Deer,當我想它來檢測是否有中間初始,然後拉出JohnDoeJaneyDeer。我用Left,Right,MidInStr擺弄了很多,無濟於事。


替換

check = Left(strDir, InStr(1, strDir, ".xlsx", vbTextCompare) - 10) 

''THE ISSUE IS CONTAINED HEREIN 
If InStr(1, check, " * ", vbTextCompare) > 0 Then 
    first = Trim(Left(check, Len(check) - InStr(1, check, " ", vbTextCompare) - 2)) 
    last = Trim(Right(check, Len(check) - InStr(1, check, " ", vbTextCompare) - 2)) 
Else 
    first = Trim(Left(check, Len(check) - InStr(1, check, " ", vbTextCompare))) 
    last = Trim(Right(check, Len(check) - InStr(1, check, " ", vbTextCompare))) 
End If 
''END ISSUE 

dateofbirth = mid(strDir, Len(strDir) - 12, 2) & "/" & mid(strDir, Len(strDir) - 10, 2) & "/" & mid(strDir, Len(strDir) - 8, 4) 

If InStr(filename, ".xlsx") = 0 Then 
    MsgBox ("There is no file with that extension.") 
    'Possibly include code to check for .xlsm or other extensions. 
    Exit Sub 
ElseIf (Len(filename) - Len(Replace(filename, " ", ""))) < 2 Then 
    MsgBox ("File name format does not match expected format. File name format is FIRST M LAST mmddyyyy.xlsx") 
    'Possibly include code to check for misnamed files. 
    Exit Sub 
Else 
    filename = strDir 
    filename = mid(filename, 1, InStr(filename, ".xlsx") - 1) 
    dateofbirth = mid(filename, InStrRev(filename, " ") + 1) 
    filename = mid(filename, 1, InStrRev(filename, " ") - 1) 

    first = mid(filename, 1, InStr(filename, " ") - 1) 
    filename = mid(filename, InStr(filename, " ") + 1) 

    last = mid(filename, InStrRev(filename, " ") + 1) 
    middlename = Trim(mid(filename, 1, InStr(filename, " "))) 
End If 

dateofbirth = mid(dateofbirth, 1, 2) & "/" & mid(dateofbirth, 3, 2) & "/" & mid(dateofbirth, 5, 4) 

'Preserved for later use. 
'namesData = Split(Replace(strDir, ".xlsx", ""), " ") 
'first = namesData(0) 
'If UBound(namesData) = 3 Then 
' middlename = namesData(1) 
' last = namesData(2) 
' dateofbirth = namesData(3) 
'ElseIf UBound(namesData) = 2 Then 
' last = namesData(1) 
' dateofbirth = namesData(2) 
'End If 

,並添加

reviewNameUserform.middle_Text.Text = middlename 
+2

不要''通過space' split'然後測試數的每個元素的第一個字符。在那之前使用所有元素。 – findwindow

回答

1

假設你的文件名有相似的格式的時候,你可以嘗試使用以下碼。 filename可以是John Doe 01011980.xlsxJaney B Deer 02031983.xlsx

If InStr(filename, ".xlsx") = 0 Then 
    MsgBox "missing .xlsx" 
ElseIf (Len(filename) - Len(Replace(filename, " ", ""))) < 2 Then 
    MsgBox "input format seems weird, not enough spaces" 
Else 
    filename = Mid(filename, 1, InStr(filename, ".xlsx") - 1) 
    dateofbirth = Mid(filename, InStrRev(filename, " ") + 1) 
    filename = Mid(filename, 1, InStrRev(filename, " ") - 1) 

    first = Mid(filename, 1, InStr(filename, " ") - 1) 
    filename = Mid(filename, InStr(filename, " ") + 1) 

    last = Mid(filename, InStrRev(filename, " ") + 1) 
    middlename = Trim(Mid(filename, 1, InStr(filename, " "))) 
End If 

代碼首先刪除的.xlsx結尾時,需要從最終的生日(最後空間,直到結束),然後獲取第一個名稱(啓動,直到第一個空格),然後是姓(最後空間,直到結束),剩下的就是中間名。

+0

通過不斷重新指定變量以排除正在使用的內容,可以減少格式化文件名的絕佳方式。我添加了'dateofbirth = mid(dateofbirth,1,2)&「/」&mid(dateofbirth,3,2)&「/」&mid(dateofbirth,5,4)',這樣它就會顯示格式化,蛋糕。還允許我使用中間名字首字母,這是我原本想要做的,但由於我在選擇文件名稱中選擇正確的字符串時遇到了問題,因此放棄了。沒有使用陣列,我傾向於遠離,因爲他們嚇倒我。我不知道爲什麼。 – MCSythera

1

這裏有一個建議....利用FindWindow函數尖端

Private Sub nextname_Click() 

    Dim strDir As String, first As String, last As String, dateofbirth As String, check As String 

    strDir = Worksheets("Sheet1").Range("A1").Text 
    strDir = Dir 
    If strDir = "" Then 
     Unload Me 
     MsgBox ("I couldn't find any other client files by that name.") 
     Exit Sub 
    End If 

    check = Left(strDir, InStr(1, strDir, ".xlsx", vbTextCompare) - 10) 

    ''THE SOLUTION IS CONTAINED HEREIN 
     check = Trim(check) 
     first = Split(check, " ")(LBound(Split(check, " "))) 
     last = Split(check, " ")(UBound(Split(check, " "))) 

    ''END SOLUTION 

    dateofbirth = mid(strDir, Len(strDir) - 12, 2) & "/" & mid(strDir, Len(strDir) - 10, 2) & "/" & mid(strDir, Len(strDir) - 8, 4) 

    Worksheets("Sheet1").Range("A1") = "C:\filepath\" & strDir 

    reviewNameUserform.first_Text.Text = first 
    reviewNameUserform.last_Text.Text = last 
    reviewNameUserform.dob_Text.Text = dateofbirth 

希望這有助於...

+0

這確實奏效,儘管它很簡單,但我認爲就後面的操作數據(例如存儲在數組中)和我個人對其工作原理的個人理解而言,它的效果比其他兩個答案的效率要低那不是你的錯)。另外兩個答案也是一箇中間詞首字母,我原本放棄了,因爲我自己缺乏從文件名中拉字符串的經驗,但被賦予使用它的能力是額外的好處。一個很好的答案雖然解決了這個問題。 – MCSythera

+0

快樂它有點幫助。我以爲你不需要中間名字。當姓氏包含像「EL Paso」這樣的空間時,這個代碼可能會受到限制... – Hadi

1

,您可以使用分割功能。 所以,你的這部分代碼:

''THE ISSUE IS CONTAINED HEREIN 
If InStr(1, check, " * ", vbTextCompare) > 0 Then 
    first = Trim(Left(check, Len(check) - InStr(1, check, " ", vbTextCompare) - 2)) 
    last = Trim(Right(check, Len(check) - InStr(1, check, " ", vbTextCompare) - 2)) 
Else 
    first = Trim(Left(check, Len(check) - InStr(1, check, " ", vbTextCompare))) 
    last = Trim(Right(check, Len(check) - InStr(1, check, " ", vbTextCompare))) 
End If 
''END ISSUE 

將被修改爲:

'USING SPLIT 
namesData = Split(Replace(strDir,".xlsx","")," ") 
first = namesData(0) 
If UBound(namesData)=3 Then 
    last = namesData(2) 
    dateofbirth = namesData(3) 
ElseIf UBound(namesData)=2 Then 
    last = namesData(1) 
    dateofbirth = namesData(2) 
End If 
+0

這將會崩潰,如'JohnDoe 01011980.xlsx'的文件名。更好地使用'elseif ubound(namesData)= 2' –

+0

我會遍歷每個元素並測試編號... – findwindow

+0

我測試了這一點,它的工作方式與我選擇的代碼一樣好。我只是不太喜歡數組,但我可以看到有一個變量具有所有元素的變量是非常有用的。我可能會稍後再回來,並使用它來代替另一個,因爲數組存儲的限制比使用一個變量重新定義的變量更少。我還在'If'語句中加入了'middlename = namesData(1)'來提取中間的首字母,這很好。 – MCSythera

相關問題