回答編集履歴

1

見直しキャンペーン中

2023/07/21 08:31

投稿

TN8001
TN8001

スコア9862

test CHANGED
@@ -1,361 +1,181 @@
1
1
  「定数等に置き換えようにも数が多すぎて、手作業ではやっていられない」みたいな状況なんでしょうか?
2
2
 
3
-
4
-
5
3
  マクロは使ったことない上、今はJavaScriptなんですかね??
6
-
7
4
  全然わからないのでコンソールアプリで作ってみました。
8
5
 
9
6
 
10
-
11
-
12
-
13
7
  `NuGet`で`Microsoft.CodeAnalysis.VisualBasic`を入れること。
14
-
15
8
  ```VBNET
16
-
17
9
  Imports System.IO
18
-
19
10
  Imports Microsoft.CodeAnalysis
20
-
21
11
  Imports Microsoft.CodeAnalysis.VisualBasic
22
-
23
12
  Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
24
13
 
25
-
26
-
27
14
  Module Module1
28
-
29
15
  Sub Main()
30
-
31
16
  CreateDummyFiles()
32
17
 
33
-
34
-
35
18
  Dim rewriter = New MethodBlockRewriter
36
-
37
19
  For Each filePath In Directory.GetFiles("test", "*.vb")
38
-
39
20
  Dim text = File.ReadAllText(filePath)
40
-
41
21
  Dim tree = SyntaxFactory.ParseSyntaxTree(text)
42
-
43
22
  text = rewriter.Visit(tree.GetRoot).ToFullString
44
-
45
23
  File.WriteAllText(filePath, text)
46
-
47
24
  Next
48
-
49
25
  End Sub
50
26
 
51
-
52
-
53
27
  Private Class MethodBlockRewriter
54
-
55
28
  Inherits VisualBasicSyntaxRewriter
56
-
57
29
  Public Overrides Function VisitMethodBlock(ByVal node As MethodBlockSyntax) As SyntaxNode
58
-
59
30
  Dim mss = TryCast(node.BlockStatement, MethodStatementSyntax)
60
-
61
31
  If mss Is Nothing Then
62
-
63
32
  Return MyBase.VisitMethodBlock(node)
64
-
33
+ End If
34
+ ' メソッド名がHoge1でなければ何もしない
35
+ If mss.Identifier.ValueText <> "Hoge1" Then
36
+ Return MyBase.VisitMethodBlock(node)
65
37
  End If
66
38
 
67
- ' メソッド名がHoge1でなければ何もしない
39
+ ' メソッドブロックを文字列に
40
+ Dim text = node.ToFullString
68
41
 
69
- If mss.Identifier.ValueText <> "Hoge1" Then
42
+ Dim name As String = ""
70
-
71
- Return MyBase.VisitMethodBlock(node)
43
+ Dim tbs = TryCast(node.Parent, TypeBlockSyntax)
72
-
44
+ If tbs IsNot Nothing Then
45
+ ' クラス名orモジュール名取得
46
+ name = tbs.BlockStatement.Identifier.ValueText
73
47
  End If
74
48
 
75
-
76
-
77
- ' メソッドブロックを文字列に
78
-
79
- Dim text = node.ToFullString
80
-
81
-
82
-
83
- Dim name As String = ""
84
-
85
- Dim tbs = TryCast(node.Parent, TypeBlockSyntax)
86
-
87
- If tbs IsNot Nothing Then
88
-
89
- ' クラス名orモジュール名取得
90
-
91
- name = tbs.BlockStatement.Identifier.ValueText
92
-
93
- End If
94
-
95
-
96
-
97
49
  ' 置換
98
-
99
50
  text = text.Replace("MsgBox(""Hoge1"")", $"MsgBox(""{name}.Hoge1"")")
100
51
 
101
52
 
102
-
103
-
104
-
105
53
  ' 実際はそんな単純な置換ではないでしょうから
106
-
107
54
  ' 他と絶対被らない目印を入れて
108
-
109
55
  ' エディタ等の正規表現で一括置換したらいいんじゃないでしょうか
110
-
111
56
  'text = text.Replace("MsgBox(", "'Replace Point!! MsgBox(")
112
57
 
113
58
 
114
-
115
-
116
-
117
59
  ' textからMethodBlockSyntaxを作り直して返す(もっといい書き方がありそう
118
-
119
60
  Return SyntaxFactory.ParseSyntaxTree(text).GetCompilationUnitRoot.Members(0)
120
-
121
61
  End Function
122
-
123
62
  End Class
124
63
 
125
-
126
-
127
64
  Private Sub CreateDummyFiles()
128
-
129
65
  Directory.CreateDirectory("test")
130
-
131
66
  File.WriteAllText("test\Module1.vb",
132
-
133
67
  "Module Module1
134
-
135
68
  Sub Hoge1()
136
-
137
69
  Dim hoge1 As Integer
138
-
139
70
  MsgBox(""Hoge1"")
140
-
141
71
  End Sub
142
-
143
72
  Sub Hoge2()
144
-
145
73
  Dim hoge2 As Integer
146
-
147
74
  MsgBox(""Hoge2"")
148
-
149
75
  End Sub
150
-
151
76
  End Module
152
-
153
77
  ")
154
78
 
155
-
156
-
157
79
  File.WriteAllText("test\Class1.vb",
158
-
159
80
  "Class Class1
160
-
161
81
  Function Hoge1() As Integer
162
-
163
82
  MsgBox(""Hoge1"")
164
-
165
83
  Return 0
166
-
167
84
  End Function
168
-
169
85
  Function Hoge2() As Integer
170
-
171
86
  MsgBox(""Hoge2"")
172
-
173
87
  Return 0
174
-
175
88
  End Function
176
-
177
89
  End Class
178
-
179
90
  ")
180
-
181
91
  End Sub
182
-
183
92
  End Module
184
-
185
93
  ```
186
-
187
94
  C#コードをそのままVBに移したつもりですが、あっているか自信がないのでC#コードも載せます^^;
188
-
189
- ```C#
95
+ ```cs
190
-
191
96
  using System.IO;
192
-
193
97
  using Microsoft.CodeAnalysis;
194
-
195
98
  using Microsoft.CodeAnalysis.VisualBasic;
196
-
197
99
  using Microsoft.CodeAnalysis.VisualBasic.Syntax;
198
100
 
199
-
200
-
201
101
  namespace Questions244513
202
-
203
102
  {
204
-
205
103
  internal class Program
206
-
207
104
  {
208
-
209
105
  private static void Main()
210
-
211
106
  {
212
-
213
107
  CreateDummyFiles();
214
108
 
215
-
216
-
217
109
  var rewriter = new MethodBlockRewriter();
218
-
219
110
  foreach(var filePath in Directory.GetFiles(@"test", "*.vb"))
220
-
221
111
  {
222
-
223
112
  var text = File.ReadAllText(filePath);
224
-
225
113
  var tree = SyntaxFactory.ParseSyntaxTree(text);
226
-
227
114
  text = rewriter.Visit(tree.GetRoot()).ToFullString();
228
-
229
115
  File.WriteAllText(filePath, text);
230
-
231
116
  }
232
-
233
117
  }
234
118
 
235
-
236
-
237
119
  private class MethodBlockRewriter : VisualBasicSyntaxRewriter
238
-
239
120
  {
240
-
241
121
  public override SyntaxNode VisitMethodBlock(MethodBlockSyntax node)
242
-
243
122
  {
244
-
245
123
  var mss = node.BlockStatement as MethodStatementSyntax;
246
-
247
124
  // メソッド名がHoge1でなければ何もしない
248
-
249
125
  if(mss?.Identifier.ValueText != "Hoge1") return base.VisitMethodBlock(node);
250
126
 
251
-
252
-
253
127
  // メソッドブロックを文字列に
254
-
255
128
  var text = node.ToFullString();
256
129
 
257
-
258
-
259
130
  // クラス名orモジュール名取得
260
-
261
131
  var name = (node.Parent as TypeBlockSyntax)?.BlockStatement.Identifier.ValueText;
262
-
263
132
  // 置換
264
-
265
133
  text = text.Replace("MsgBox(\"Hoge1\")", $"MsgBox(\"{name}.Hoge1\")");
266
134
 
267
135
 
268
-
269
-
270
-
271
136
  // 実際はそんな単純な置換ではないでしょうから
272
-
273
137
  // 他と絶対被らない目印を入れて
274
-
275
138
  // エディタ等の正規表現で一括置換したらいいんじゃないでしょうか
276
-
277
139
  //text = text.Replace("MsgBox(", "'Replace Point!! MsgBox(");
278
140
 
279
141
 
280
-
281
-
282
-
283
142
  // textからMethodBlockSyntaxを作り直して返す(もっといい書き方がありそう
284
-
285
143
  return SyntaxFactory.ParseSyntaxTree(text).GetCompilationUnitRoot().Members[0];
286
-
287
144
  }
288
-
289
145
  }
290
146
 
291
-
292
-
293
147
  private static void CreateDummyFiles()
294
-
295
148
  {
296
-
297
149
  Directory.CreateDirectory("test");
298
150
 
299
-
300
-
301
151
  File.WriteAllText(@"test\Module1.vb",
302
-
303
152
  @"Module Module1
304
-
305
153
  Sub Hoge1()
306
-
307
154
  Dim hoge1 As Integer
308
-
309
155
  MsgBox(""Hoge1"")
310
-
311
156
  End Sub
312
-
313
157
  Sub Hoge2()
314
-
315
158
  Dim hoge2 As Integer
316
-
317
159
  MsgBox(""Hoge2"")
318
-
319
160
  End Sub
320
-
321
161
  End Module
322
-
323
162
  ");
324
163
 
325
-
326
-
327
164
  File.WriteAllText(@"test\Class1.vb",
328
-
329
165
  @"Class Class1
330
-
331
166
  Function Hoge1() As Integer
332
-
333
167
  MsgBox(""Hoge1"")
334
-
335
168
  Return 0
336
-
337
169
  End Function
338
-
339
170
  Function Hoge2() As Integer
340
-
341
171
  MsgBox(""Hoge2"")
342
-
343
172
  Return 0
344
-
345
173
  End Function
346
-
347
174
  End Class
348
-
349
175
  ");
350
-
351
176
  }
352
-
353
177
  }
354
-
355
178
  }
356
-
357
179
  ```
358
180
 
359
-
360
-
361
181
  **注意** この単純な変換元コードでは想定通りに動きましたが、書き方によっては動かないかもしれません(VBもRoslynもよくわかっておりません)