Excel VBA 質問スレ Part63

■ このスレッドは過去ログ倉庫に格納されています
2019/09/16(月) 19:34:59.04ID:emfTAhXr0
!extend:checked:vvvvv:1000:512

ExcelのVBAに関する質問スレです
コード書き込みや作成依頼もOK

※前スレ
Excel VBA 質問スレ Part62
https://mevius.5ch.net/test/read.cgi/tech/1561303297/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
2019/10/13(日) 23:07:03.97ID:exOKfr5u0
>>260
配列で数字の添え字じゃなくて好きなワードを使いたい時に
あとDictionaryの場合は検索がめちゃくちゃ速いから大量データの検索に
2019/10/13(日) 23:09:26.19ID:YeAfr+Aea
>>241
こういうこと?
Sub 検索()
Const COL_C As Long = 3
Const COL_F As Long = 6
Const COL_O As Long = 15
Dim nSetRow As Long
nSetRow = 5
Dim nRow As Long
For nRow = 5 To 17
If Not IsExistValue(Cells(nRow, COL_C).Value) Then
Cells(nSetRow, COL_O).Value = Cells(nRow, COL_C).Value
nSetRow = nSetRow + 1
End If
Next
For nRow = 5 To 21
If Not IsExistValue(Cells(nRow, COL_F).Value) Then
Cells(nSetRow, COL_O).Value = Cells(nRow, COL_F).Value
nSetRow = nSetRow + 1
End If
Next
End Sub
2019/10/13(日) 23:09:42.80ID:YeAfr+Aea
Function IsExistValue(ByVal pValue As Variant) As Boolean
IsExistValue = True
Const COL_Y As Long = 25
Dim nRow As Long
For nRow = 5 To 25
If Cells(nRow, COL_Y).Value = pValue Then
Exit Function
End If
Next
IsExistValue = False
End Function
2019/10/13(日) 23:20:25.51ID:rkAEaYhN0
>>260
Keywordが重複できないから必ず一意なデータセットができる。
2019/10/14(月) 00:48:24.78ID:2bLpiP0X0
2シートを連結する際、それぞれの各行をクラスインスタンスに代入&コレクション化してるのですが連結方法に悩んでいます

Personクラス(pID, 氏名, 名字プロパティ, 生年月日,...)→Persons.Add Personインスタンス, str(pID)
Diaryクラス(dID, pID, 作成日, 本文,...)→Diaries.Add Diaryインスタンス, str(dID)
'出力
Dim d as Diary
For each d in Diaries
if(存在チェック) then xxx = Persons.Item(d.pID).名字
Next d

現在上記のように回してますが、より楽に書けるor固いor保守しやすい...実装があれば教えて頂きたいです
現状はプロパティの予測表示がされないのが微妙に使いにくいのと、そもそもコレクションにおけるkeyの動作をよく分かっていません
2019/10/14(月) 01:24:56.78ID:wVIK+1B50
>>260
existsが便利
数数えたり、行番号取り出したり、キャッシュの管理に使ったり
for eachで中身を全部取り出そうとしたら投入順が保証されないのが少し残念
2019/10/14(月) 09:29:31.58ID:+oSE7p5I0
VBAでOPENしたファイルを引数で渡す事は出来ますか?
こんな感じで処理したいのですが、「#1」って変数では無いのでしょうか

Sub foo()
Open "TESTFILE" For Output As #1 ' Open file for output.
Call write_(#1,"content")
Close #1
End Sub

Function write_(filenumber, content)
Write filenumber, content
End Function
2019/10/14(月) 09:38:41.74ID:LU4QFSeP0
>>254
>>255
ホント。
プログラムに対する理解のないバカ上司とか、
コーディングの真っ最中に、平気でコピー取りを要求してきたりするからな。
2019/10/14(月) 12:22:02.07ID:UlmNQm1da
>>267
ファイル番号は1-255の範囲で常に固定値でやるなら引数で渡さずにどこも#1でいいかと思う
FreeFileって関数があってこれは番号を任意に付番してくれるので
たとえば
Dim nNo as Integer
nNo = FreeFile
Open .... #nNo
って書くこともできる
このnNoを引数に指定してもいいかもね
2019/10/14(月) 12:27:42.70ID:+oSE7p5I0
>>269
行けました!ありがとうございます
ナンバー記号「#」の詳細ってMSDNかどこかにありますか?

Sub foo()

Dim nNo As Integer
nNo = FreeFile

Open "TESTFILE" For Output As nNo ' Open file for output.
Call write_(nNo, "conteaasnt")
Close #1

End Sub

Function write_(nNo, content)
Write #nNo, content
End Function
2019/10/14(月) 14:39:32.50ID:aC+4aHxsx
>>265
Persons、Diariesをコレクションにしている理由は、「Person、Diaryという2つのカスタムクラスの集合オブジェクト」という意味論以外に、何か実装的な理由はあるのかな?

例えば、2つのコレクションクラスに格納するデータの型が一様でないからCollectionじゃないとリスト化できないとか、多態のためにCollectionクラスをインターフェース継承させているとか

そういう事情がないならば、Keyの存在確認手段を持たないCollectionクラスではなく、Keyの存在確認を行うExistsメソッドを持つDictionaryを使うのが実装的には楽だと思う
pID・Person、pID・Diaryの二種類のペアに対応するDictionaryを個別に作ってpIDでリレーション確認するイメージ(各DictionaryではpIDをKeyとしておく)

そもそもRemoveやAddといった基本的な機能はCollectionとDictionaryとで共通しているし、Dictionaryの方が動作も早いしね
2019/10/14(月) 14:43:11.09ID:ghhHmrX1a
>>270
自分は見たことないですね
なんとなくですが自分は常に#をつける派です
それとcloseも#nNoかと
2019/10/14(月) 15:37:37.47ID:g9W5x9G3d
言語リファレンスでも#は省略可能となっているだけで、説明はどこにも見当たらない
古いBASICとの互換性で残してあるだけだと思う
2019/10/14(月) 15:51:24.60ID:+oSE7p5I0
>>272-273
あれ、じゃあなんでしょうねこれ
コンソールで
?#1
ではエラーになるので、ただの数値ではなくなるみたい
#1=2
も出来ない。なんとなくリテラルか参照っぽいですが、何でしょうね
openなどの時にしか使えないのでしょうか
2019/10/14(月) 15:54:12.83ID:2bLpiP0X0
>>271
ありがとうございます
コレクションを選択した理由は特にありません
(あえて挙げるなら、コレクションにまとめるリファレンスが最初に目に付いた です)

>pID・Person、pID・Diaryの二種類のペアに対応するDictionaryを個別に作ってpIDでリレーション確認するイメージ(各DictionaryではpIDをKeyとしておく)
言葉足らずですみません。Diaryクラス側ではpIDが重複しdIDが主キーとなるので、一意に取得できません。(この認識も間違っていたらすみません...)
エラー処理がExistsで済むのは明確なメリットですね。Collectionでは、調べた限りではOnErrorGoToで飛ばす方法しか見つけられませんでした
ひとまず、Diary側のループで取得したpIDでPersonDictionaryにExistsをかける 方法を試してみようと思います。
2019/10/14(月) 16:00:13.52ID:pMfnFO5+0
>>274
#1の中身は文字列じゃないよ
2019/10/14(月) 16:32:13.39ID:9SF/tSaH0
>>274
> openなどの時にしか使えないのでしょうか
そう言うことだろ
2019/10/14(月) 17:26:42.75ID:J7mWSp9Bx
>>275
複数のDiaryインスタンスが共通のpIDを持つならば、連結を二重化したらいいんじゃないだろうか

まずpIDをキーとするDiary用のDictionaryをまず作っておいて、
同じpIDを持つDiaryインスタンスをまとめたDictionaryかCollectionをItemとして持たせる形にすればいいと思う

構造的に表すと
(Key[i] = pID, Item[i] = (Key[j] = dID, Item[j] = Diary))

みたいな感じ
279デフォルトの名無しさん (ワッチョイ bfad-la4p)
垢版 |
2019/10/14(月) 22:48:09.17ID:PwgP8aUB0
VBAで表からその左の行を検索したいのですがどうしたらいいでしょうか?
Dim rng As Range
Set rng = ws_siriaru.Range("D:L").Find(ken4, LookAt:=xlWhole)
If rng Is Nothing Then rng
MsgBox ""ない
Exit Sub
End If
siriaru = Range("C" & rng.Row).Value
gouki = siriaru
label_siri = gouki
では表示はされるのですがうまくいきませんでした。
2019/10/14(月) 23:16:54.59ID:2bLpiP0X0
>>278
重ねてありがとうございます。

なるほど。Dictionaryの各要素を、そのkeyに対応するインスタンスの集合とするんですね
1key対1レコード という考えしか無かったので目から鱗です
2019/10/15(火) 00:00:45.56ID:Nq3iWAMG0
>>279
説明する時「うまくいく」とか「うまくいかない」という単語は使ってはいけない
2019/10/15(火) 00:02:27.41ID:0b9bW6T40
>>279
どういった表示がされて、実際に欲しい情報とどこが違うでしょうか?

Range("D:L")をken4で完全一致検索をかけ、最初に見つかったセルの行番号を取得
その行のC列セルの値をsiriaruに代入

という点ではプログラムに間違いはありません
2019/10/15(火) 00:30:22.92ID:i09LlRYux
>>280
その通り
そのようにすれば、Diaryのインスタンス集合全体に対してpIDの存在確認をすることも出来るし、pID, dIDという2つのプロパティ値を使って目的のDiaryオブジェクトを取り出すこともできる
2019/10/15(火) 04:19:47.75ID:/i2LKWgur
>>279
siriaru=ws_siriaru.Range("C" & rng.Row).Value
2019/10/15(火) 08:12:41.36ID:/HnZFUztx
>>279
siriaruに値を代入するときに参照しているシートがシリアルのシートじゃなくて別シートになってると思う
siriaru = ws_siriaru.Range("C" & rng.Row).Value
に変えたらうまくいくのでは
2019/10/15(火) 18:45:11.44ID:opa9jcIha
>>270
close もopenと同じ番号のnNo によ
2019/10/15(火) 21:12:27.40ID:OH7oWYO6r
>>236
最初からVariantに入れるのが正解では?
2019/10/15(火) 21:28:52.40ID:NB8YI5GFx
>>287
Variant型は便利だけどRangeオブジェクトを突っ込むためだけの変数で使用するにはねぇ
実際のデータ型を明示しないぶんコードが読みにくくなるしコーティング時にインテリセンスも利かなかったりとデメリットの方が目立つ
実行時エラーの原因って感じ
289デフォルトの名無しさん (ワッチョイ bfad-la4p)
垢版 |
2019/10/15(火) 22:36:34.14ID:LwOOuMgG0
リストの表示について
以下の表示の際最終行後ろのセルが空白だった場合最終行が表示されません。
なぜでしょうか?
LastRowではA列の最終行を指定しているので間違いではないと思うのですが
最終行のみ全てのセルに数値を入れていないと最終行に反映されないみたいです;。
With ws_kiki
    LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
myData = .Range(.Cells(1, 1), .Cells(Rows.Count, 13).End(xlUp)).Value

End With
With list_ken
.ColumnCount = 13
.ColumnWidths = "20;60;50;50;50;70;70;50;50;50;50;50"
.List = myData
2019/10/15(火) 22:58:43.53ID:Nq3iWAMG0
>>289
M列で値が入ってる一番下のセルまでが範囲のようだが
2019/10/15(火) 23:33:50.79ID:NB8YI5GFx
>>289
あなたsiriaruの人でしょ
もういい加減お金払って誰かに教えてもらうか、MSDNのVBAのリファレンスを読み込んできちんと勉強すべきだとおもうよ
会社で使ってるマクロのコードベタ貼りしてるのも本当に宜しくない

今回の問題は、せっかくLastRowにA列の使用セルの最終行の行インデックスを格納しているのに、myDataに入れる値のセル範囲指定でそのLastRowの値を使っていないことが原因でしょ
自分の頭をちゃんと使って書いてる?

myData = .Range(.Cells(1, 1), .Cells(LastRow, 13)).Value

と書き直せば終わり
2019/10/16(水) 00:02:02.46ID:TVv1yadl0
この人の問題は質問内容よりも質問文が意味不明なこと
状況を全く何も知らない相手に説明するということを考えながら質問文を書くようにしよう
2019/10/16(水) 00:19:19.45ID:GI0GqC4Qx
こういう構造的思考力のない人がコピペ&コピペで作り上げた野良マクロが企業の負債になっていくんだよね
2019/10/16(水) 00:30:12.53ID:4U9etGee0
ワークシートのスクリーンショットとか図で説明してもらわないと訳がわからない
2019/10/16(水) 07:23:15.57ID:Qp+et4KT0
.Net系もやってる人に質問です
列挙体に属性付けて指定すると数値の他に定義した文字列返す方法があると思うんですけど
アレをVBAで行う方法は有りますか?
Constで定義すれば出来ないことは無いんですがなんかダサくて・・・
2019/10/16(水) 08:23:24.91ID:GI0GqC4Qx
>>295
構造体配列とかクラスとかで擬似的に再現するしかないんじゃないの
2019/10/16(水) 08:32:09.52ID:M09TXdK2a
>>295
どうでもいいだろ
VBAなんか使ってること自体が恥辱なのに何を今更
2019/10/16(水) 12:35:11.58ID:IY04c/q/M
>>295
簡単には無理でしょ
.NETも取得するのはそれなりに面倒だし
2019/10/16(水) 12:54:37.89ID:swoRisr+p
>>296
そのためにクラスを作るとVBAの場合はひとクラス1モジュールファイルを切らないといけないし、
フォルダ分けも出来ないので、クラスを作る方法は後々クラスファイルが煩雑になる可能性があるのでやめておきます。

構造体や配列を使うのは少し大掛かりな気もしますが、お陰で何となくイメージがわきました。
DictionaryとかCollectionとかのValueペアのオブジェクトを使って、key側にenumで使用している番号、
Value側に文字列を設定して、enumに紐付けてやるような感じでやろうかなと。
ただ、修正が入るときに手間が掛かるようだとあまり意味がないのでその辺の構成は気をつけて作るような
感じですかね。ありがとうございました。

>>297
どんな言語だろうと自分なりに構成を考えて作っていくのは大事だと思いますよ。
今回の件は無理して作る程のものではありませんが
きちんと部品化しておけばまた違った局面で使うことが出来るので、
自分のためにも、引き継ぐ人のためにも大事だと思います。それはどの言語でも同じでしょう。
2019/10/16(水) 13:35:11.75ID:QJqyol2eM
引き継ぎを考えるなら郷に入れば郷に従えで普通にプレーンに書いた方がいい
VBAに限ったことではないけど、変なオナニーされるのが一番迷惑なんだよ
2019/10/16(水) 18:05:45.54ID:vKUJ5JTra
>>297
なんでここに居るん?
2019/10/16(水) 18:50:39.66ID:QVKO1shPa
>>295
ダサくてもそれが今の実力だからな
2019/10/16(水) 19:41:40.73ID:3AmZTcsu0
>>295
それは.NetでExcelを動かせばいいんじゃ・・。
2019/10/16(水) 22:11:30.10ID:Y2Xm51x3x
>>299
値のペアを返す参照構造を作りたいんだったらワークシートを素直に使ってハッシュテーブルで運用した方がメンテ工数が少ないのでは
ワークシートはGUI化された多次元配列なのでね
セルの値の読み書きでイベントハンドラに制御が渡るのが嫌なら別だが
2019/10/16(水) 22:19:50.46ID:IiLmkjOX0
フィルタされたデータをシート上で複数繋がった状態で選択したとする。その場合にそれら『のみ』を取得することはできるんだろか?教えていただきたいです。
バージョンはexcel2016です。

例)
以下がフィルタされたセル。
 A1←選択
 A4←選択
 A5
上の場合にA1とA4のみを取得する。A2とA3は取得しない。
2019/10/16(水) 22:43:21.53ID:Y2Xm51x3x
フィルタ抽出されたセル範囲だけを取得したいなら、
Range("A1:A5").SpecialCells(xlCellTypeVisible).Select

の一行で終わると思う
Range.SpecialCellsプロパティが可視セルだけを返すよう、引数に列挙定数xlCellTypeVisibleを渡せばいい
Range("A1:A5")のフィルタ範囲は必要に応じて変えてね
307デフォルトの名無しさん (ワッチョイ bfad-la4p)
垢版 |
2019/10/16(水) 23:52:50.60ID:e5YHiPLP0
>>289です。
わぉ!辛辣ですね。こちらで聞いて大分やりたいことが出来ましたので
後は自分で考えていきます。
参考書を聞きかじってインターネットからまるまるパクったコードをデバックしまくって改造
していきます。
ちなみに今回のコードは
LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
myData = .Range(.Cells(1, 1), .Cells(Rows.Count, 13).End(xlUp)).Value
これが正しいコードでした。
myData = .Range(.Cells(LastRow, 1), .Cells(1, 13).End(xlUp)).Value
最終列の最終行を取得してたのでそこが空白だと最終列が反映されないことが判明しました
2019/10/17(木) 01:09:44.53ID:QyNdzX/10
>>307
間違ってるけど…
2019/10/17(木) 01:12:20.23ID:cDk85Tz1x
>>307
読んでて頭痛のするような酷い文章だな
デバックじゃなくてデバッグだろ

しかも単なるコード改変のことをデバッグとか言ってるしさ
本気でデバッグしなきゃならないときにスキルのないこういうコピペコーダーは何の役にも立たないのに
会社の資産であるコードをこんな掲示板に晒しといて何やってんだか
2019/10/17(木) 01:14:14.21ID:cDk85Tz1x
>>307
しかもコード間違ってるし
311デフォルトの名無しさん (ワッチョイ 1ead-b2ak)
垢版 |
2019/10/17(木) 01:19:38.31ID:KClIintl0
>>309
会社の資産でもなんでもないけど?
1から自分で休日に作ってるんだけど?会社で使うものでもないんでw
2019/10/17(木) 01:23:29.50ID:cDk85Tz1x
>>311
仕事でもないのにわざわざVBAを使うってただの苦行じゃん
PythonとかJavaScriptとか使えばいいのに
2019/10/17(木) 01:26:24.43ID:QyNdzX/10
インターネットからまるまるパクることを1から自分で作るとは言わない
2019/10/17(木) 01:28:05.18ID:cDk85Tz1x
控え目に言ってアホだよな
2019/10/17(木) 07:12:10.84ID:f3ZcAy7Ha
vbaの話で別の言語とか出してマウント取りたい人って何なんだろうね
職場の同僚も大変そうw
2019/10/17(木) 07:30:47.90ID:cDk85Tz1x
何か心に刺さったのかな?
他言語持ち出されたときにマウント取られたと思うのは大抵そう受け取る側に問題があるぞ
2019/10/17(木) 08:03:49.72ID:p8i0Yvjup
>>316
一応ここVBAのスレだから
せめてJavascriptやPythonでExcelが扱えるようになってから来なさい
2019/10/17(木) 08:25:30.37ID:kDxfJkPvM
前提もなしに>>312みたいなこと書くやつは要らんっていう話だろ
2019/10/17(木) 08:36:06.38ID:GRl5SZlQM
結局なんらかの形で表データを閲覧するならエクセルで閉じた方が楽だなと思う
2019/10/17(木) 10:14:17.57ID:V7Fv8DAn0
結局、表入力が簡単で確実なんだよな
なんつか心配がいらない
処理はpythonのほうが楽だがエクセル
ファイルのみで管理できるってことも含め
総合的にはVBAいいんだよね 雑な意味で
データと処理が一つにまとまってるんで
オブジャクト思考的ってか
2019/10/17(木) 10:31:18.04ID:fkyJRw1v0
発音に「ャ」の要素はないかと。
2019/10/17(木) 10:39:10.24ID:V7Fv8DAn0
API呼び出せるんだから
大概のことはVBAでどうにか
なってしまうんだよな。小さい会社、つまり
会社の9割以上はVBA程度で
十分なんだよな まあVBAがおもちゃで
なくてはならないって立場は分からんでもないがw
2019/10/17(木) 15:37:20.74ID:e7g1u0+T0
エクセルの表から始まる作業ならVBAがいいとおもうよ
例えば客からの電話注文をエクセルに一度まとめていて、それを管理画面に反映させる作業とか・・・
スクリプトを動かす必要のないサイトならブラウザ開かずにボタンポチで完了するし
(いつもちゃんと登録されてるのか不安がられるが)
2019/10/17(木) 16:07:50.37ID:gr44XWYWM
俺ならそういうのはGoogle Spreadsheet使うかな
一旦ローカルに置くのは無駄
2019/10/17(木) 16:46:25.92ID:e7g1u0+T0
>>324
みんなエクセルで管理したがるので
2019/10/17(木) 18:09:32.12ID:p8i0Yvjup
まぁVBAやって育ってくるとその内
VB.Netとかやるようになって
Web系を扱うようになると
ASP.Netとかやる機会も出て来るから
SQLと同じようにHTMLとかCSSとか
JavaScriptとか必要に迫られて
片手間で覚えるようになるから大丈夫。

別に今のままで良ければそのまま
VBAやってればいいわけだし。
327デフォルトの名無しさん (ワッチョイ 9f94-vCPd)
垢版 |
2019/10/17(木) 19:58:00.62ID:EDPspb6d0
VBAの最大のデメリットは何でもVBAでやろうとする脳になる事
こんな化石のような言語でやるのは苦行そのもの
今更覚える意味すらない
2019/10/17(木) 20:00:11.81ID:2ydjDz1a0
そんな意味のないもののスレをわざわざ見に来る意味はあるの
2019/10/17(木) 20:41:45.44ID:j32AuqLC0
>>322
さすがにエクセルで納品ってわけにいかないから
適当にインターフェースつくるが中身はVBAで
十分ってのはあるな

>>327
そんなに言語仕様クソか?
小綺麗にまとまってると思うけどな
純粋さはないが使い勝手は悪くない
2019/10/17(木) 20:55:38.52ID:a6vhi3mO0
時代遅れ感があるのと、どう書くべきかが分かりにくいのと、エラーメッセージがクソなのを除けばそこまででもないな
シートモジュールやブックモジュールが邪魔すぎる。標準モジュールだけで良かった
そしてエラーメッセージの「修正:式」はあまりに不親切。ここはアップデートかけてくれてもいいのに
2019/10/17(木) 21:02:24.20ID:9rn0DJ5qa
他の言語と比較すればマトモだと思う
2019/10/17(木) 21:18:35.64ID:uSN2w5EG0
>どう書くべきかが分かりにくいのと

それは言語の問題じゃない。

英語の文法はわかりにくい → そりゃお前が日本人だからそう思うだけだろ!
日本語の文法はわかりにくい → そりゃお前がアメリカ人だからそう思うだけだろ!
2019/10/17(木) 21:22:30.75ID:a6vhi3mO0
出ました定義したがりw
2019/10/17(木) 22:03:59.43ID:uSN2w5EG0
>>333
え?
違うの?
じゃあわかりにくいのは、あんたの能力の問題だね。
俺にはわかりやすいから。
2019/10/17(木) 22:53:38.34ID:lelQayoPx
シートモジュールとブックモジュールはただのクラスモジュールだからなぁ
コンストラクタとデストラクタがないぶんシートモジュールだけが特殊だが
2019/10/17(木) 23:08:12.09ID:a6vhi3mO0
そう、オブジェクトが何か分かっていれば何の問題もない
しかし現実問題、Excelを使うのは一般事務。setっていつ使うのかなかなか理解できない層が中心なのだ
2019/10/17(木) 23:49:25.80ID:lelQayoPx
implementsステートメントで組み込みのワークシートオブジェクトのインターフェースを継承すればシート用モジュールになります、って感じの仕組みならよかったよな
ユーザー定義クラスだって属性宣言を先頭に持って来ればクラス用モジュールになりますって感じの扱いで良かったし
2019/10/18(金) 00:09:11.06ID:RulO09Tc0
オマイラのスーパーテクを俺に継承してくれや。
2019/10/18(金) 01:12:13.81ID:Kn6PgWdna
>>338
VBAを上手く使うというのはつまるところ「可能な限りVBAを使わない」なので教えろと言われても難しいな
業務フローのレベルからVBAが最小限になるように設計するんだよ
2019/10/18(金) 01:29:19.13ID:sk0uHZY+x
PowerQueryとかPowerPivotとか標準的なExcelの組み込み機能で出来る作業をVBAでやってるのを見るけどああいうのも時間の無駄だわな
2019/10/18(金) 06:28:43.63ID:rwfK/g890
vbaで何でも出来るから全部vbaでやる・・・それがシンプルでカッコイイ事だと思いこんでいた時期がありました
2019/10/18(金) 08:24:07.64ID:RulO09Tc0
武器を持った奴が相手ならVBAを使わざるを得ない
2019/10/18(金) 08:28:11.67ID:RulO09Tc0
>>339
>>340
>>341
レスありがとう。万能なExcelに選ばれた言語、それが、VBA!

VBA王に俺はなる!
2019/10/18(金) 12:32:43.64ID:xgSV8V5dp
>>343
そんなこと言わんと
VBAをとっとと卒業してC#辺りに入りなさいな。
他の言語も勉強するとVBAのコードの組み方もガラッと変わるよ。

例えば.Net系をやればクラスやインターフェースの理解がグッと深まるから
テスト項目も減らせる組み方が出来るし、変更点の改修も少ない組み方が出来るようになる。
2019/10/18(金) 12:35:35.40ID:YN+VnyL5M
そういう所まで進みたい人とそうでも無い人がいるって事を理解しなよ
2019/10/18(金) 12:45:18.66ID:dVFolCOsM
>>345
どちらにせよVBAを極めても意味はないという帰結に違いはないな
2019/10/18(金) 12:47:17.38ID:as8acMuSa
本当にプログラミング好きな人はVBAじゃ満足しないだろ
VBAを極めるとはどういう状態かわかりませんが
2019/10/18(金) 12:55:00.41ID:YN+VnyL5M
>>346
ちょっと理解出来ないです
2019/10/18(金) 14:34:31.34ID:C4vTbpVj0
2つ質問させてください

Sub Main()
Dim n As Long
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws1cell As Range
Dim r As Long
Set ws1 = Worksheets(1)
Set ws2 = Worksheets(Worksheets.Count)
n = ws1.Cells(Rows.Count, 5).End(xlUp).Row + 5
For r = 1 To ws2.Cells(Rows.Count, 5).End(xlUp).Row
Set ws1cell = ws1.Range("E:E").Find(ws2.Cells(r, 5).Value, lookat:=xlWhole)'項目名が違い、達成率が100%でない場合は開始日・終了日・達成率を更新
If ws1cell Is Nothing And ws2.Cells(r, 10) < 1 Then
ws1cell.Range(ws1.Cells(n, 8), ws1.Cells(n, 10)).Value = ws2.Range(ws2.Cells(r, 8), ws2.Cells(r, 10)).Value
n = n + 1
Else'達成度が進んだ場合は開始日・終了日・達成度を更新
If ws1cell.Value = ws2.Cells(r, 5).Value And ws1cell.Offset(0, 3) < ws2.Cells(r, 8) Then
ws1cell.Offset(0, 3) = ws2.Cells(r, 8)
ws1cell.Offset(0, 4) = ws2.Cells(r, 9)
ws1cell.Offset(0, 5) = ws2.Cells(r, 10)
End If
End If
Next r
End Sub
項目名が違う時にエラーが出てしまいます
If ws1cell is nothingの部分で変数を解放しているから問題なのかと考えていましたが、ws1cell = "" , 0に書き換えてもウォッチウィンドウで見ると
set ws1cellを通った後もnothingのままになっていました
setを通れば変数を定義出来ると思っていたのですが、どのようにすれば解決できますか?
よろしくお願いします
2019/10/18(金) 14:35:51.85ID:C4vTbpVj0
改行エラーが出てしまったため2つに分けました
VBAを使い始めて1ヶ月弱なのですがC#でエクセルを操作出来るようになりたいと考えております
VBAで作ったプログラムを元にして、C#を学ぶ方法は無いでしょうか?
書き方が全然違うとの話を聞いたので、諦めて最初から覚えるしかないかと途方に暮れております
よろしくお願いします
2019/10/18(金) 14:58:09.86ID:irJy6XEP0
なんでvbaでできる事をいちいちC#でやろうとするか意味解らんよ
2019/10/18(金) 15:40:17.44ID:71CpEOK5d
今後C#を使う予定であれば、VBAで出来る事だとしてもC#を使う時間を増やした方が習得が早いと思ったからです
2019/10/18(金) 19:07:24.11ID:Kd4kiXAf0
>>349
一番目のIF文の条件間違えてね?
これだとNothingのときに中で使うことになっちゃうよ
2019/10/18(金) 19:07:29.23ID:7YrisXmNd
文法が全く違う言語だから何をどう頑張ろうがベースにはできない。
せいぜい同じ結果を出せるかどうかの演習材料にしかならんよ。
2019/10/18(金) 19:11:29.96ID:vO06UtuM0
>>350
覚えるっていうか移植先の作法に従って書き換えるだけ
356デフォルトの名無しさん (ワッチョイ 1ef7-V+wO)
垢版 |
2019/10/18(金) 19:17:45.06ID:Kd4kiXAf0
>>349 書き直すけど
If ws1cell Is Nothing And ws2.Cells(r, 10) < 1 Then は
ws1cellがNothingのときじゃないと通らない。なのにそのあとでws1cell.Range〜とかws1cell.Offsetなんてやると当然エラーになる。
Not ws1cell Is Nothing みたいに反転させないと。
2019/10/18(金) 19:35:18.82ID:YN+VnyL5M
セルがどういう時にnothingになるのか分かって条件に指定してるのか怪しい気がする
2019/10/18(金) 19:38:22.84ID:xgSV8V5dp
>>350
VBAやって一ヶ月ならそのままVBAやっておけばいいよ。別に急いでるわけでもないんでしょ?

VBAやってツールの幾つかでも作って、コードがそらで書けるようになったらまずVB.Netをやる。

文法はそっくりだけど構成が違うし見たこともない命令も沢山あるから多分苦労すると思う。
でもここさえ乗り越えてしまえばObject指向の何たるかが大体解るようになるからそうしたらC#に入ればいいよ。

C#はVBA→VB.Netのときとは逆に構成がVB.Netとよく似ていて文法が違う。あと型が厳しい。
でも、ま、VB.Netを覚えてしまえばC#も7割方理解したって言えると思う。

何も手を着けてない状態なら最初からC#をやることを勧めるけど
折角VBA始めたんだから遠回りにはなるかも知れないけどそういう楽な方法もあるよ。
2019/10/18(金) 20:19:32.44ID:L2N4rS5+M
それ以前に>>349
> 項目名が違う時にエラーが出てしまいます
じゃなくてどの行でどんなエラーが出てるのかを書けよ
ID:Kd4kiXAf0は超親切だからレスしてくれてるけど普通はスルーされて終わりだよ
2019/10/18(金) 21:48:21.62ID:/2Um4idM0
>>356
条件が反対だったんですね…
If文の条件をもう一度書き直してみます
丁寧にありがとうございます

>>355
>>358
将来的にはエクセルに集約しすぎて重くなってしまっているデータを、誰でも使えるように軽くしたいと考えている位なので、まずはプログラムに慣れて行きます
プログラムの考え方だけでも次のステップの練習問題には使えると思うので、数をこなしてみます
ありがとうございます

>>359
すみませんでした
次から質問する時は気をつけます
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況