質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

809閲覧

[VB.net]特定メソッド内のみ置換する方法

kanoka

総合スコア5

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

1グッド

0クリップ

投稿2020/03/01 22:47

編集2020/03/02 11:53

VB.netでの質問です。
Visual Studio2017でのMacroを使用し特定のメソッド内の特定の部分だけを置換する方法はありますでしょうか。
文字を挿入することはできるのですが、特定のメソッド内のみを指定する方法がわかりません。

以下例文
VB.net
Private Sub Hoge1()

Dim hoge1 as integer

MsgBox("Hoge1")

End Sub

Private Sub Hoge2()

Dim hoge2 as integer

MsgBox("Hoge2")

End Sub

上記のHoge2()のメソッド内のみMsgBoxの内容を変えたといった場合どうすればよいでしょうか。 また方法についてはMacroでなくでも大丈夫です。 [追記] 申し訳ございません。情報が足りなさ過ぎました。 例として、ある作業フォルダに上記と同じコードが記述されたファイルが複数あるとして、 その作業フォルダ内にあるすべてのファイルのHoge2()内のMsgBoxの内容だけをを一括で置換したいということです。 Hoge1()内の内容は変えずにHoge2()の内容だけ変えたいです。 質問の仕方が下手で申し訳ございません。
TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/03/01 23:37

変数を使えばいいのでは?
退会済みユーザー

退会済みユーザー

2020/03/02 00:36

そもそも何がしたいのでしょう? XY 問題になっていて、Y を質問してませんか?
kanoka

2020/03/02 11:54

返信遅れて申し訳ございません。 情報を追記しました。 質問の仕方が下手で申し訳ないです。
Zuishin

2020/03/02 12:11

他に方法がありそうな感じですね。その方法によって何がしたいのかを最初から書いた方が適切な回答が得られると思います。
YAmaGNZ

2020/03/02 12:21

追記を見ても、変数や定数、リソース等で一括管理すれば、そこを書き換えるだけで対応できそうですが
kanoka

2020/03/02 22:45

回答ありがとうございます。 もう少し考えてみることにします!
guest

回答1

0

ベストアンサー

「定数等に置き換えようにも数が多すぎて、手作業ではやっていられない」みたいな状況なんでしょうか?

マクロは使ったことない上、今はJavaScriptなんですかね??
全然わからないのでコンソールアプリで作ってみました。

NuGetMicrosoft.CodeAnalysis.VisualBasicを入れること。

VBNET

1Imports System.IO 2Imports Microsoft.CodeAnalysis 3Imports Microsoft.CodeAnalysis.VisualBasic 4Imports Microsoft.CodeAnalysis.VisualBasic.Syntax 5 6Module Module1 7 Sub Main() 8 CreateDummyFiles() 9 10 Dim rewriter = New MethodBlockRewriter 11 For Each filePath In Directory.GetFiles("test", "*.vb") 12 Dim text = File.ReadAllText(filePath) 13 Dim tree = SyntaxFactory.ParseSyntaxTree(text) 14 text = rewriter.Visit(tree.GetRoot).ToFullString 15 File.WriteAllText(filePath, text) 16 Next 17 End Sub 18 19 Private Class MethodBlockRewriter 20 Inherits VisualBasicSyntaxRewriter 21 Public Overrides Function VisitMethodBlock(ByVal node As MethodBlockSyntax) As SyntaxNode 22 Dim mss = TryCast(node.BlockStatement, MethodStatementSyntax) 23 If mss Is Nothing Then 24 Return MyBase.VisitMethodBlock(node) 25 End If 26 ' メソッド名がHoge1でなければ何もしない 27 If mss.Identifier.ValueText <> "Hoge1" Then 28 Return MyBase.VisitMethodBlock(node) 29 End If 30 31 ' メソッドブロックを文字列に 32 Dim text = node.ToFullString 33 34 Dim name As String = "" 35 Dim tbs = TryCast(node.Parent, TypeBlockSyntax) 36 If tbs IsNot Nothing Then 37 ' クラス名orモジュール名取得 38 name = tbs.BlockStatement.Identifier.ValueText 39 End If 40 41 ' 置換 42 text = text.Replace("MsgBox(""Hoge1"")", $"MsgBox(""{name}.Hoge1"")") 43 44 45 ' 実際はそんな単純な置換ではないでしょうから 46 ' 他と絶対被らない目印を入れて 47 ' エディタ等の正規表現で一括置換したらいいんじゃないでしょうか 48 'text = text.Replace("MsgBox(", "'Replace Point!! MsgBox(") 49 50 51 ' textからMethodBlockSyntaxを作り直して返す(もっといい書き方がありそう 52 Return SyntaxFactory.ParseSyntaxTree(text).GetCompilationUnitRoot.Members(0) 53 End Function 54 End Class 55 56 Private Sub CreateDummyFiles() 57 Directory.CreateDirectory("test") 58 File.WriteAllText("test\Module1.vb", 59"Module Module1 60 Sub Hoge1() 61 Dim hoge1 As Integer 62 MsgBox(""Hoge1"") 63 End Sub 64 Sub Hoge2() 65 Dim hoge2 As Integer 66 MsgBox(""Hoge2"") 67 End Sub 68End Module 69") 70 71 File.WriteAllText("test\Class1.vb", 72"Class Class1 73 Function Hoge1() As Integer 74 MsgBox(""Hoge1"") 75 Return 0 76 End Function 77 Function Hoge2() As Integer 78 MsgBox(""Hoge2"") 79 Return 0 80 End Function 81End Class 82") 83 End Sub 84End Module

C#コードをそのままVBに移したつもりですが、あっているか自信がないのでC#コードも載せます^^;

cs

1using System.IO; 2using Microsoft.CodeAnalysis; 3using Microsoft.CodeAnalysis.VisualBasic; 4using Microsoft.CodeAnalysis.VisualBasic.Syntax; 5 6namespace Questions244513 7{ 8 internal class Program 9 { 10 private static void Main() 11 { 12 CreateDummyFiles(); 13 14 var rewriter = new MethodBlockRewriter(); 15 foreach(var filePath in Directory.GetFiles(@"test", "*.vb")) 16 { 17 var text = File.ReadAllText(filePath); 18 var tree = SyntaxFactory.ParseSyntaxTree(text); 19 text = rewriter.Visit(tree.GetRoot()).ToFullString(); 20 File.WriteAllText(filePath, text); 21 } 22 } 23 24 private class MethodBlockRewriter : VisualBasicSyntaxRewriter 25 { 26 public override SyntaxNode VisitMethodBlock(MethodBlockSyntax node) 27 { 28 var mss = node.BlockStatement as MethodStatementSyntax; 29 // メソッド名がHoge1でなければ何もしない 30 if(mss?.Identifier.ValueText != "Hoge1") return base.VisitMethodBlock(node); 31 32 // メソッドブロックを文字列に 33 var text = node.ToFullString(); 34 35 // クラス名orモジュール名取得 36 var name = (node.Parent as TypeBlockSyntax)?.BlockStatement.Identifier.ValueText; 37 // 置換 38 text = text.Replace("MsgBox(\"Hoge1\")", $"MsgBox(\"{name}.Hoge1\")"); 39 40 41 // 実際はそんな単純な置換ではないでしょうから 42 // 他と絶対被らない目印を入れて 43 // エディタ等の正規表現で一括置換したらいいんじゃないでしょうか 44 //text = text.Replace("MsgBox(", "'Replace Point!! MsgBox("); 45 46 47 // textからMethodBlockSyntaxを作り直して返す(もっといい書き方がありそう 48 return SyntaxFactory.ParseSyntaxTree(text).GetCompilationUnitRoot().Members[0]; 49 } 50 } 51 52 private static void CreateDummyFiles() 53 { 54 Directory.CreateDirectory("test"); 55 56 File.WriteAllText(@"test\Module1.vb", 57@"Module Module1 58 Sub Hoge1() 59 Dim hoge1 As Integer 60 MsgBox(""Hoge1"") 61 End Sub 62 Sub Hoge2() 63 Dim hoge2 As Integer 64 MsgBox(""Hoge2"") 65 End Sub 66End Module 67"); 68 69 File.WriteAllText(@"test\Class1.vb", 70@"Class Class1 71 Function Hoge1() As Integer 72 MsgBox(""Hoge1"") 73 Return 0 74 End Function 75 Function Hoge2() As Integer 76 MsgBox(""Hoge2"") 77 Return 0 78 End Function 79End Class 80"); 81 } 82 } 83}

注意 この単純な変換元コードでは想定通りに動きましたが、書き方によっては動かないかもしれません(VBもRoslynもよくわかっておりません)

投稿2020/03/03 09:13

編集2023/07/21 08:31
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kanoka

2020/04/10 00:10

反応がかなり遅くなってしまい申し訳ございません。 コードまで書いていただき、またロジック部分も参考になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問