2016-05-23 204 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

相关问题