Board logo

標題: [發問] 請問如何從一行文字長字串中截取需要的短字串 [打印本頁]

作者: lone_tiger0303    時間: 2011-6-25 17:38     標題: 請問如何從一行文字長字串中截取需要的短字串

AO欄位內的字串有統一排列方式,在每一個#字號後面在帶出"職稱"與"姓名"。每一個字串可能同時有二個以上的#字號,如何用VBA方式篩選出我僅需要的"姓名",並將"姓名"個別抓到BJ、BK、BL…欄位
作者: luhpro    時間: 2011-6-25 23:21

本帖最後由 luhpro 於 2011-6-25 23:27 編輯

依據你的需求抓取指定字串的癥結在於 :
1. 找到 "#" 與 "$" 的位置,
2. 確定職稱都是只有兩個字, 否則將很難確認到底名字是從哪裡開始抓的
要找到某個字串的位置 Excel VBA 有個指令 instr 可以達成此目的.

值得一題的是,
不論 instr 還是 mid(left、right、len 皆同) 對於中文字都是視為 1 個字的長度,
這在抓取報表形式的文字時是非常不適合用的指令.
例如 :

2011/06/25 張三       16:33:18
2011/06/25 李四娘     16:55:21

若用 mid(sstr,21,8) 抓第一行可以正常抓到時間 16:33:18,
但第二行卻會抓成 6:55:21 ,
所以比較好的區隔方式會是在要抓的字串右方放上用特定符號,
用 instr 抓取該符號再往前推一定長度.

然而在 c 語言中一個中文字則是視為 2 個字的長度,
在此類需求的使用上真的是比 Excel VBA 方便多了.

底下是我想到的程式 :
  1. Sub nn()
  2.   Dim sStr$, sColumn$
  3.   Dim iI%, iBegin%, iMark%, iEnd%, iRows%, iRow%
  4.   Dim iCol%, iCol1%, iNext%
  5.   
  6.   sColumn = "BJ"
  7.   iCol1 = 0
  8.   For iI = Len(sColumn) - 1 To 0 Step -1
  9.     iMark = Asc(Mid(sColumn, iI + 1, 1)) - 64
  10.     iCol1 = iCol1 + iMark * 26 ^ -(iI = 0)
  11.   Next iI
  12.   iRows = Cells(Rows.Count, "AO").End(xlUp).Row
  13.   For iRow = 2 To iRows
  14.     sStr = CStr(Cells(iRow, "AO").Value)
  15.     iBegin = InStr(1, sStr, "#") + 1
  16.     iNext = InStr(iBegin + 1, sStr, "#") + 1
  17.     If iNext < iBegin Then iNext = iBegin
  18.     iCol = iCol1
  19.     Do Until iBegin > iNext
  20.       iEnd = InStr(iBegin, sStr, "$") - 1
  21.       Do Until iBegin > iEnd
  22.         iMark = InStr(iBegin, sStr, "#") - 1
  23.         If iMark > iBegin + 6 Then iMark = iEnd
  24.         If iMark < iBegin Then iMark = iEnd
  25.         Cells(iRow, iCol).Value = Trim(Mid(sStr, iBegin + 2, iMark - iBegin - 1))
  26.         iBegin = iMark + 2
  27.         iCol = iCol + 1
  28.       Loop
  29.       iNext = InStr(iBegin + 1, sStr, "#") + 1
  30.       If iNext > iBegin Then iBegin = iNext
  31.     Loop
  32.   Next iRow
  33. End Sub
複製代碼

作者: diabo    時間: 2011-6-26 01:10

本帖最後由 diabo 於 2011-6-26 01:12 編輯
  1. Sub 資料剖析()

  2.    '取得資料最後一列
  3.     last_row = Sheet1.[AO65536].End(xlUp).Row   
  4.    '取得填入姓名之欄數
  5.     col_bgn = Sheet1.Range("BJ1").Column
  6.    
  7.     For r = 2 To last_row         
  8.        '欲解析之原始資料內容
  9.         raw_data = Sheet1.Range("AO" & r).Value               
  10.        '以#分割字串為陣列(Array)
  11.         arr_Name = Split(raw_data, "#")
  12.         For n = 1 To UBound(arr_Name)
  13.            '第n個姓名回填資料欄數
  14.             c = col_bgn + n
  15.            '取出職稱+姓名+....
  16.             raw_name = Trim(arr_Name(n))            
  17.            '取的$位置
  18.             pos = InStr(1, raw_name, "$")
  19.            '取出姓名--假設職稱皆為兩個字(請自行將AD2的「接帶待」改為「接待」)
  20.             Sheet1.Cells(r, c).Value = Mid(raw_name, 3, IIf(pos = 0, 255, pos - 3))
  21.         Next
  22.     Next

  23. End Sub
複製代碼

作者: lone_tiger0303    時間: 2011-6-27 09:22

感謝luhpro與diabo幫忙




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)