Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


10918 / 13644 ツリー ←次へ | 前へ→

【19161】文字列の切り取りについて けんた 04/10/24(日) 6:37 質問[未読]
【19162】Re:文字列の切り取りについて Hirofumi 04/10/24(日) 7:43 回答[未読]
【19163】Re:文字列の切り取りについて Hirofumi 04/10/24(日) 8:32 回答[未読]
【19166】Re:文字列の切り取りについて ちゃっぴ 04/10/24(日) 12:33 回答[未読]
【19167】Re:文字列の切り取りについて Kein 04/10/24(日) 13:02 回答[未読]
【19169】Re:文字列の切り取りについて ちゃっぴ 04/10/24(日) 13:52 発言[未読]
【19170】Re:文字列の切り取りについて Kein 04/10/24(日) 14:17 発言[未読]

【19161】文字列の切り取りについて
質問  けんた  - 04/10/24(日) 6:37 -

引用なし
パスワード
   はじめまして。お知恵をお借りしたくて投稿いたしました。
セルA1に下記のいずれか一つのSQL文が入るとします。
SQL文中の()内の文字(1,2,3,4,5など)を取り出してA2に出力したいと考えて
います。
こういった場合、どうすればよいのでしょうか?
それぞれSQL文の長さが違うためMid()関数ではうまくいきそうにありません。
よろしくお願いいたします。

Insert into A values(1,2,3,4,5);
または
Insert into B values(1,2,3);
または
Insert into C values(1,2);

【19162】Re:文字列の切り取りについて
回答  Hirofumi  - 04/10/24(日) 7:43 -

引用なし
パスワード
   こんなFunctionを作って、ユーザー定義関数として使うか、
VBAのコードから使うかすれば善いのでは?

Public Function GetData(vntValue As Variant) As Variant

  Const cstrFindTop As String = "values("
  Const cstrFindEnd As String = ")"
  
  Dim lngPosTop As Long
  Dim lngPosEnd As Long
  Dim lngLenght As Long
  
  lngLenght = Len(cstrFindTop)
  lngPosTop = InStr(1, vntValue, cstrFindTop, vbTextCompare)
  lngPosEnd = InStr(1, vntValue, cstrFindEnd, vbTextCompare)
  
  GetData = Mid(vntValue, lngPosTop + lngLenght, _
              lngPosEnd - lngPosTop - lngLenght)
  
End Function

ユーザー定義関数として使うなら、A2のセルに

=GetData(A1)

で善いのでは?

【19163】Re:文字列の切り取りについて
回答  Hirofumi  - 04/10/24(日) 8:32 -

引用なし
パスワード
   この方が確実かも?

Public Function GetData(vntValue As Variant) As Variant

  Const cstrFindTop As String = "values("
  Const cstrFindEnd As String = ");"
  
  Dim lngPosTop As Long
  Dim lngPosEnd As Long
  Dim lngLenght As Long
  
  GetData = ""
  lngLenght = Len(cstrFindTop)
  lngPosTop = InStr(1, vntValue, cstrFindTop, vbTextCompare)
  If lngPosTop = 0 Then
    Exit Function
  End If
  lngPosEnd = InStr(lngPosTop + lngLenght + 1, _
              vntValue, cstrFindEnd, vbTextCompare)
  
  GetData = Mid(vntValue, lngPosTop + lngLenght, _
              lngPosEnd - lngPosTop - lngLenght)
  
End Function

【19166】Re:文字列の切り取りについて
回答  ちゃっぴ  - 04/10/24(日) 12:33 -

引用なし
パスワード
    > SQL文中の()内の文字(1,2,3,4,5など)を取り出してA2に
> 出力したいと考えています。

こういった場合、正規表現を使いこなせるようになると
効率的な文字列抽出ができるようになります。

'要参照 Microsoft VBScript Regular Expressions 5.5

Sub GetArgs(strTarget As String)
  Dim objRegExp  As VBScript_RegExp_55.RegExp
  Dim colMatches As VBScript_RegExp_55.MatchCollection
  Dim objMatch  As VBScript_RegExp_55.Match
  
  Set objRegExp = New VBScript_RegExp_55.RegExp
  With objRegExp
    .Global = True
    .IgnoreCase = True
    .Pattern = "\([^\(\)]*\)"
    Set colMatches = .Execute(strTarget)
  End With
  
  For Each objMatch In colMatches
    With objMatch
      Debug.Print Mid$(.Value, 2, .Length - 2)
    End With
  Next objMatch
End Sub


ここら辺でお勉強ください。

Clinick's Clinic on Scripting: 正規表現による Visual Basic Scripting Edition (VBScript) の機能強化
http://www.microsoft.com/japan/msdn/columns/scripting/scripting051099.asp

【19167】Re:文字列の切り取りについて
回答  Kein  - 04/10/24(日) 13:02 -

引用なし
パスワード
   Sub Rep_St()
  Dim x As Long, y As Long
  Dim ReS As String
 
  With Range("A1")
   x = InStr(1, .Value, "(")
   y = InStr(1, .Value, ")") + 1
   ReS = Mid$(.Value, x, y - x)
  End With
  Range("A2").Value = ReS
End Sub

ぐらいでいいのでは ?

【19169】Re:文字列の切り取りについて
発言  ちゃっぴ  - 04/10/24(日) 13:52 -

引用なし
パスワード
   ▼Kein さん:
>Sub Rep_St()
>  Dim x As Long, y As Long
>  Dim ReS As String
> 
>  With Range("A1")
>   x = InStr(1, .Value, "(")
>   y = InStr(1, .Value, ")") + 1
>   ReS = Mid$(.Value, x, y - x)
>  End With
>  Range("A2").Value = ReS
>End Sub
>
>ぐらいでいいのでは ?

私も、前はそんな感じでやっていたのですが・・・

データが常にきれいな形(必ず"("→")")ならよいですが、
汚いデータだと「y - x」が負の値の時のエラー処理とかが
面倒くさくて、正規表現に切り替えた経緯があります。

【19170】Re:文字列の切り取りについて
発言  Kein  - 04/10/24(日) 14:17 -

引用なし
パスワード
   "(" か ")" が見つからないときに中止するなら

If x = 0 Or y = 0 Then Exit Sub

を追加するぐらいで出来ますね。
正規表現を使うのも良いのですが、既知の条件に応じてなるべく簡単なコードにする、
というのも後々のメンテを考えると大切だと考えます。ま、配布を目的にするなら、
汎用性や予測できないエラーを考えて、いろいろと対策が必要ですけどね。質問者は
その点について触れていないので、提示された条件でストレートにコードを
組めば良い、と思いましたが。

10918 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free