[リストへもどる]
一括表示

投稿時間:2004/05/31(Mon) 22:59
投稿者名:YADORI
Eメール:
URL :
タイトル:
英数字以外の削除の仕方
  いつも利用させて頂いてお入ります。

 strOneLineDatに英数字、漢字、記号などが入り乱れて入力されます。
 そのデータを英数字のみの状態のデータとしたい時に私は下記の様に記述したのですが
 データが多くなると処理速度がかなり低下します。

 Dim strOneLineDat As String
  Dim strTemp       As String
  Dim intLoop       As Integer
  Dim intAsc        As Integer
  '
  strOneLineDat = "aAcd-0324-PあOI*POいL\AA"
  '
  strTemp = ""
  For intLoop = 1 To Len(strOneLineDat)
      intAsc = Asc(Mid$(strOneLineDat, intLoop, 1))
      If (intAsc >= 97 And intAsc <= 122) _
         Or (intAsc >= 65 And intAsc <= 90) _
         Or (intAsc >= 48 And intAsc <= 57) Then
         strTemp = strTemp + Mid$(strOneLineDat, intLoop, 1)
      End If
  Next
  strOneLineDat = strTemp

  MsgBox strOneLineDat  '結果------------> aAcd0324POIPOLAA
  
  速度を上げるためにもっと簡略した方法など有ればご教授頂きたくお願い致します。

投稿時間:2004/06/01(Tue) 08:19
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: 英数字以外の削除の仕方
この場合の処理は文字列の連結に99.5%かかっており、比較の部分は0.5%しかかかって
いません。
従って、文字列の連結をいかに早くするかにあります。
文字列が短い場合は連結も時間はかからないのですが、長くなると極端に遅くなります。
そこである程度までは、都度連結し、ある程度長くなったら連結をつなぎ変えます。
説明するより下記を試して見て下さい。
私のマシンでは、48.6 秒→ 1.1 と極端に早くなりました。
(あまりにも早いので間違っていないか心配ですが!。(^_^) )

Option Explicit
Private Declare Function timeGetTime Lib "winmm.dll" () As Long

Private Sub Command1_Click()
Dim lngStartTime    As Long
  Dim strOneLineDat As String
  Dim strTemp       As String
  Dim strTemp1       As String
  Dim intLoop       As Integer
  Dim intAsc        As Integer
  Dim dat As String

  Dim i As Integer
  
  strOneLineDat = "aAcd-0324-PあOI*POいL\AA"
  lngStartTime = timeGetTime
  strTemp = ""
 strTemp1 = ""
    For i = 1 To 10000
        For intLoop = 1 To Len(strOneLineDat)
            dat = Mid$(strOneLineDat, intLoop, 1)
            intAsc = Asc(dat)
            If (intAsc >= 97 And intAsc <= 122) _
                Or (intAsc >= 65 And intAsc <= 90) _
                Or (intAsc >= 48 And intAsc <= 57) Then
                strTemp1 = strTemp1 & dat
                If Len(strTemp1) > 50 Then
                    strTemp = strTemp & strTemp1
                    strTemp1 = ""
                End If
            End If
        Next intLoop
    Next i
    strOneLineDat = strTemp & strTemp1
    Label1.Caption = "timeGetTime  : " & (timeGetTime - lngStartTime) / 1000
End Sub

投稿時間:2004/06/01(Tue) 09:07
投稿者名:LESIA
Eメール:
URL :
タイトル:
Re^2: 英数字以外の削除の仕方
文字列の連結は遅いので、置き換えるようにするともっと速くなります。
私のマシンでは花ちゃんの方法でも5秒くたい掛かりましたが、この方法だと0.5秒に
なりました(^^)

Private Sub Command2_Click()
  Dim lngStartTime  As Long
  Dim strOneLineDat As String
  Dim strTemp As String
  Dim intLoop As Integer
  Dim intAsc As Integer
  Dim dat As String
  Dim i As Integer
  Dim n As Integer
  
  strOneLineDat = "aAcd-0324-PあOI*POいL\AA"
  lngStartTime = timeGetTime
  strTemp = Space$(Len(strOneLineDat))
    For i = 1 To 10000
        n = 1
        For intLoop = 1 To Len(strOneLineDat)
            dat = Mid$(strOneLineDat, intLoop, 1)
            intAsc = Asc(dat)
            If (intAsc >= 97 And intAsc <= 122) _
                Or (intAsc >= 65 And intAsc <= 90) _
                Or (intAsc >= 48 And intAsc <= 57) Then
                Mid$(strTemp, n, 1) = dat
                n = n + 1
            End If
        Next intLoop
    Next i
    strOneLineDat = Left$(strTemp, n)
    Label2.Caption = "timeGetTime  : " & (timeGetTime - lngStartTime) / 1000
End Sub

投稿時間:2004/06/01(Tue) 12:15
投稿者名:nanashi
Eメール:
URL :
タイトル:
Re^3: 英数字以外の削除の仕方
If文も変えると、もうほんの少し速くなりますね。

    If dat Like "[0-9a-zA-Z]" Then

ループカウンタをLong型にすると速くなるっていう話を以前聞きましたが、全然変わらなかったですf^_^;

投稿時間:2004/06/01(Tue) 13:40
投稿者名:Renard
Eメール:
URL :
タイトル:
Re^4: 英数字以外の削除の仕方
配列をうまく使えれば、これが一番速かったです。

Private Sub Command4_Click()
    Dim lngStartTime    As Long
    Dim strOneLineDat As String
    Dim strTemp(1 To 10000)       As String
    Dim intLoop       As Integer
    Dim dat As String
    Dim i As Integer
    
    strOneLineDat = "aAcd-0324-PあOI*POいL\AA"
    lngStartTime = timeGetTime
    
    For i = 1 To 10000
        For intLoop = 1 To Len(strOneLineDat)
            dat = Mid$(strOneLineDat, intLoop, 1)
            If dat Like "[0-9A-Za-z]" Then
                strTemp(i) = strTemp(i) & dat
            End If
        Next intLoop
    Next i
    strOneLineDat = Join(strTemp, "")
    Label4.Caption = "timeGetTime  : " & (timeGetTime - lngStartTime) / 1000
    
End Sub

投稿時間:2004/06/01(Tue) 15:07
投稿者名:YADORI
Eメール:
URL :
タイトル:
Re: 英数字以外の削除の仕方
花ちゃんさん、LESIAさん、nanashiさん、Renardさん

ご回答ありがとうございました。

いろいろな方法があるのですね(^^;)

どの回答も私では思いつかない物のばかりでしたm(_ _)m

大変参考になりました。

今後ともよろしくお願い致します。