• ベストアンサー

VBAの記述で、あるシートを別ファイルにした場合

エクセル2002で、商品を管理しています。 1列目に品番をいれると、2列目に品名が表示するようにし、 新規の品番は品名を入れると、追加登録されるようにVBAを組みました。 今度、このシート"商品"を別ファイル(商品.xls)にしたいと思うのですが、 どうしても、やり方が分かりません。 よろしくお願いします。 Public Sub Worksheet_Change(ByVal Target As Excel.Range) Dim 品番 As String Dim 品名 As String Dim i As Long With Target If .Column = 1 Then 品番 = .Text For i = 1 To 65536 If Sheets("商品").Cells(i, 1) = "" Then ActiveSheet.Cells(.Row, 2) = "" Exit For ElseIf 品番 = Sheets("商品").Cells(i, 1) Then ActiveSheet.Cells(.Row, 2) = Sheets("商品").Cells(i, 2) Exit For End If Next i End If If .Column = 2 Then 品名 = .Text 品番 = ActiveSheet.Cells(.Row, 1) If 品名 = "" Or 品番 = "" Then Else For i = 1 To 65536 If Sheets("商品").Cells(i, 1) = "" Then Sheets("商品").Cells(i, 1) = 品番 Sheets("商品").Cells(i, 2) = 品名 Exit For ElseIf 品番 = Sheets("商品").Cells(i, 1) Then Exit For End If Next i End If End If End With End Sub

  • ebis
  • お礼率54% (29/53)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.6

補足に対するお手数をおかけいたしました。早速サンプルマクロを作ってみました。以下のように操作してみて下さい。 1.商品台帳.xlsというブックと商品コードというブックを新規に作る。それぞれのブックのシート1のA1にコード・B1に商品名と入力する。 2.商品台帳.xlsのVBE画面を開き、VBEProjectの下にあるThisWorkbookをダブルクリックしてThisWorkbookのコードエディターを開く。 3.そのコードエディターに下記のコードをコピー・ペーストする。 Private Sub Workbook_Open() Dim myBook As Workbook Dim myWbn As String For Each myBook In Workbooks myWbn = myBook.Name If myBook.Name = "商品コード.xls" Then Exit Sub Next Workbooks.Open ("C:\My Documents\商品コード.xls") Workbooks("商品台帳.xls").Activate End Sub 4.Sheet1のコードエディターを開き、下記のコードをコピー・ペーストをする。 Private Sub Worksheet_Change(ByVal Target As Range) Dim myRow As Integer Dim myWsn As Worksheet Dim myCell As String Dim myRange As Range myRow = Target.Row If Target.Address = Range("A" & myRow).Address _ Or Target.Address = Range("B" & myRow).Address Then Set myWsn = Workbooks("商品コード.xls").Worksheets(1) myCell = myWsn.Range("A1").CurrentRegion.SpecialCells(xlCellTypeLastCell).Address Set myRange = myWsn.Range("A2:" & myCell).Find(Target.Value, lookat:=xlWhole) Application.EnableEvents = False If myRange Is Nothing Then If Target.Address = Range("A" & myRow).Address Then myWsn.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = Target.Value Else myWsn.Cells(Rows.Count, 2).End(xlUp).Offset(1, 0).Value = Target.Value End If Else Target.Offset(0, 1).Value = myRange.Offset(0, 1).Value Target.Offset(0, 1).Columns.EntireColumn.AutoFit End If Application.EnableEvents = True End If End Sub あなた様のおやりになりたいことが、できます。 何か不都合なことがありましたら、ご遠慮なくお知らせ下さい。修正サンプルマクロを作りたいと思います。

ebis
質問者

お礼

問題なく稼動しました。 親切に他Bookを開くマクロまで作ってもらって、助かります。 ただ、私の勉強不足でと、VBA記述のレベルが高いせいか、内容理解には時間がかかりそうです。 当面の改造とかを考え、#1の方法と合わせて使わせていただきます。 丁寧な回答ありがとうございました。

その他の回答 (5)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.5

#3の者です。#4のkazuhikoのさんほか詳しく読んでくだっさったようで、まずお礼を申し上げます。他の方ebisさんのご質問・解答の場ですが一言 言い訳めいたことを述べさせていただきます。 (1)xlPartのこと   A.縦1列の検索と決まっているのでxlPartでも良いか     と思いました。それにしてはCellsになっていますね    。Range()にしたかったのですが。   B小数例ながらテストをしており、問題なく動きましたの    でそのままにしました。   もう少し詳しい、不適当な理由がわかれば教えてください。 (2)Activateの多用の点   私自身気かひけていて、懸念を解答の末尾に書いておりま  す。今後勉強して今後は改善したいと思います。   オブジェクト宣言方式?では危ないと過去の経験から推定して、解答の締め  きられる時間を気にして、その方式でテストする時間が取れな  いと、取りあえず載せました。別のブックの場合も、   WB(1).WS(2).Range(3)で1の部分に   Book名を指定して(単一Bookの場合と同じく)参  照出来ればといつも思いますが、(今回別ブックの参照でてこずり、エラーがでて)うまくいかないケースが多いので諦めました。勉強不足と資料不足で、根本のところが迷いがあり、小生の弱点と心得ております。今後とも宜しく。

回答No.4

#No3のご回答で気になる点がありましたので、生意気ながら意見を述べさせていただきます。 1.Findメソッドで、引数のLook AtにXlpartを指定しておりますが、これでは、私が以前Findメソッドを使ってこの方法で検索をかけた結果、うまく検索ができなかったことがあります。この場合、必ずlook Atには、xlwholeを指定するべきかと思います。 2.処理するときに対象となるブックをいちいちアクティブにしているようですが、変数を2個worksheet型で宣言し、その変数にそれぞれのブックのシート名を代入すれば、もっと簡単になるのではないでしょうか。 以上気がついて点を生意気ながら書かせていただきました。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

(1)Booka.xlsのSheet1にA1:B10に コード 商品名 1 ノートA4 2 定規 4 鉛筆 5 消しゴム 6 挟み 7 マーカー 9 ボールペン 10 糊 12 ナイフ をテストで作りました。 (2)Bookb.xlsを作り保存する。 (3)Bookb.xlsを開き、そのModule1に Sub test02() Workbooks.Open ("c:\My Documents\Booka.xls") End Sub を作る。そして実行しBooka.xlsを開いておく。 ----- Bookb.xlsを開いているところで もう一つModule1に Private Sub Worksheet_Change(ByVal Target As Range) Dim z As Object 'MsgBox Target r = Target.Row c = Target.Column If c = 1 Then Windows("booka.xls").Activate Set z = ActiveWorkbook.Worksheets("Sheet1").Cells.Find(What:=Target, After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _ xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False) ' If z Is Nothing Then ' MsgBox "コード無し" ' Exit Sub ' End If x = z.Offset(0, 1) Windows("bookb.xls").Activate ActiveWorkbook.Worksheets("Sheet1").Cells(r, c + 1) = x Else End If End Sub 異なるBookを参照するため行き来するのに、Activateを多用していますが、何か別の方法があるような気がする が取りあえず載せます。小数例でテスト済み。 またオフコードの入力に対しての備えやDELやその他多用な 入力に対する対処が考えらていません。あとは宜しく。

ebis
質問者

お礼

テストさせていただきました。 検索については、はうまく動作しました。 ちょっと画面がちらつきますが。 ありがとうございました。

回答No.2

はじめまして。 1.現在1つのブック(ブックAとする)に2つのシート(商品を管理するシートと品番と品名のみを記入したシート)がある。 2.今度、品番と品名のみを記入したシートを別ブック(ブックBとする)に移動する。 3.商品を管理するシートのA列に品番を入力したとき、入力された品番をブックBの中から探し、見つかった品番に対応する品名をブックAの品番の右隣に自動で表示させる。 4.もしブックAに入力した品番がブックBになかったら、ブックBの品番が書かれている最後のセル番地のすぐ下へ入力させ、その品番に対応する品名をその右隣に入力させる。 あなた様のやられたいことはこのようなことでよろしいのでしょうか。 もし、ちがうのであれば、あなた様のおやりになりたいことを上の要領でお知らせ下さい。 私でよろしければ、サンプルマクロを作ってみたいと思います。 お手数をおかけいたしますが、よろしくお願いいたします。

ebis
質問者

補足

遅れてすみません。 全て、おっしゃられている通りです。 よろしくお願い致します。

  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.1

下の様に修正してみました。 最初の4行を追加。コード内の『Sheets("商品")』を『ws2』に変更しました。 最初の4行で参照・修正するシートを変数ws2に割り当てています。 そのため、コードの意味合いは変更していません。ブック商品は開いてある前提です。 Public → Private にしています。 検索の方法としては、For~Next とは別に、Findを使う方法もあります。 Private Sub Worksheet_Change(ByVal Target As Excel.Range)   Dim wb2 As Workbook 'ブック商品   Dim ws2 As Worksheet 'ブック商品のシート商品     Set wb2 = Workbooks("商品.xls")     Set ws2 = wb2.Worksheets("商品")   Dim 品番 As String   Dim 品名 As String   Dim i As Long   With Target     If .Column = 1 Then       品番 = .Text       For i = 1 To 65536         If ws2.Cells(i, 1) = "" Then           ActiveSheet.Cells(.Row, 2) = ""           Exit For         ElseIf 品番 = ws2.Cells(i, 1) Then           ActiveSheet.Cells(.Row, 2) = ws2.Cells(i, 2)           Exit For         End If       Next i     End If     If .Column = 2 Then       品名 = .Text       品番 = ActiveSheet.Cells(.Row, 1)       If 品名 = "" Or 品番 = "" Then       Else         For i = 1 To 65536           If ws2.Cells(i, 1) = "" Then             ws2.Cells(i, 1) = 品番             ws2.Cells(i, 2) = 品名             Exit For           ElseIf 品番 = ws2.Cells(i, 1) Then             Exit For           End If         Next i       End If     End If   End With End Sub

ebis
質問者

お礼

やはり他Bookを開く方法しかないようですね。 #6の方法と合わせて使わせていただき、うまく稼動しました。 ありがとうございました。

ebis
質問者

補足

遅れてすみません。 回答ありがとうございます。 できれば、商品.xlsを開かずに実現できないものでしょうか。

関連するQ&A

  • エクセルVBA テキストボックス処理?

    エクセル2000 VBAにて入力フォームの テキストボックス1に下記を書き込んだのですが カーソルがテキストボックス1にあるとき 他の処理(コマンドボタン、マウスにて他のテキストボックスに カーソルを移すなど)が出来ません。 フォームを閉じるときもメッセージボックスのコメントがでます。 どの処理を行ってもテキストボックス1の処理が終わってからしか 行わないようなのですが??? Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) Dim i As Integer '品番確認用 For i = 3 To 100 If Sheets("品番マスタ").Cells(i, 1) = TextBox1.Text Then Label1 = Sheets("品番マスタ").Cells(i, 2).Value 'メーカー Label2 = Sheets("品番マスタ").Cells(i, 3).Value 'タイプ Label3 = Sheets("品番マスタ").Cells(i, 4).Value '品名 Label4 = Sheets("品番マスタ").Cells(i, 5).Value '内容量 Label6 = Sheets("品番マスタ").Cells(i, 8).Value '背番号 Exit Sub End If Next i MsgBox "品番がありません" TextBox1 = "" Cancel = True End Sub どのように変更すればいいでしょうか?

  • Excel  VBAのマクロについて

    以下のようなマクロを作りました。 P4に開始番号P6に終わりの番号があるのですが、P4=P6、つまり、一つだけのシートを作成する分には問題なく動きます。しかしP4に1、P6に5と範囲を増やすとエラーが出て動きません。どこをなおしたらよろしいでしょうか? Option Explicit Sub 一括() Dim I As Worksheet Dim SheetName As String Dim Prompt As String Dim Col As Integer Dim Cell As Range Dim Row As Long Dim hani As Long For hani = Range("P4").Value To Range("P6").Value Set I = ActiveSheet SheetName = Cells(hani + 4, "K").Value & "(" & Cells(hani + 4, "B") & ")" Prompt = SheetName & "が存在します。" Sheets("基本シート").Copy After:=Sheets("基本シート") On Error GoTo 100 ActiveSheet.Name = SheetName On Error GoTo 0 Range("X3") = I.Cells(hani + 4, "B") Range("E8") = I.Cells(hani + 4, "C") Range("A13") = I.Cells(hani + 4, "D") For Col = 0 To 8 Step 4 Set Cell = I.Cells(hani + 4, "D").Offset(, Col) If Cell > 0 Then Prompt = "該当する日付がありません。" & Cell.Address On Error GoTo 100 Row = WorksheetFunction.Match(Cell, [A:A], 0) On Error GoTo 0 Cells(Row, "E") = I.Cells(hani + 4, "E").Offset(, Col) Cells(Row, "H") = I.Cells(hani + 4, "F").Offset(, Col) If Col < 8 Then Cells(Row, "Y") = I.Cells(hani + 4, "G").Offset(, Col) End If End If Next Col Next hani End 100 If Err <> 1004 Then Error Err End End If MsgBox Prompt, vbCritical Application.DisplayAlerts = False ActiveSheet.Delete Application.DisplayAlerts = True Sheets(1).Select End Sub

  • VBAデータ元から新規ブックに出力

    現在のブック内に出力されるとメモリの都合上時間がかかりすぎますそこで新規ブック1個に出力する構文を教えていただきたいのですが、宜しくお願いします。 Sub 1111() Dim c As Range Dim i As Integer, LastRow As Long Dim NewSheetName As String, MatchFlag As Boolean Application.ScreenUpdating = False NewSheetName = "" With Sheets("データ元") For Each c In .Range(.Cells(3, "B"), .Cells(Rows.Count, "B").End(xlUp)) MatchFlag = False If NewSheetName <> Year(c.Value2) & "年" & Month(c.Value2) & "月" Then NewSheetName = Year(c.Value2) & "年" & Month(c.Value2) & "月" For i = 1 To Worksheets.Count If Sheets(i).Name = NewSheetName Then Sheets(i).Cells.ClearContents MatchFlag = True Exit For End If Next i If MatchFlag = False Then Worksheets.Add after:=Worksheets(Worksheets.Count) ActiveSheet.Name = NewSheetName End If End If LastRow = Sheets(NewSheetName).Cells(Rows.Count, "A").End(xlUp).Row Sheets(NewSheetName).Cells(LastRow + 1, "A").Resize(1, 6).Value = .Cells(c.Row, "A").Resize(1, 6).Value Sheets(NewSheetName).Columns("A:F").EntireColumn.AutoFit '↑A列からF列まで自動幅調整してます Next .Activate End With Application.ScreenUpdating = True MsgBox "終了しました", vbInformation End Sub

  • EXCEL-VBAで、別ファイルのシートをコピーしてくることはできますか

    先日TTACさんに組んでいただいたプログラムに、追加したい項目があります。 追記していただきたいのは、同じディレクトリ内に入っている「A」というファイル内の「BL」「M2」「まとめ」という3つのシートを、現在のファイルにコピーするという命令です。ファイル「A」はこの3シートで構成されています。 前回は、ファイル内にこの「BL」というシートが存在するという前提で組んでいただきましたが、今回は、別ファイルからこの3つのシートをコピーしてきた後、処理をするという形にしたいのですが、できますでしょうか? 前回作って頂いたプログラムは下記通りです。 Sub Macro1() Dim datCol As Integer Dim i As Integer Set sheetBL = ThisWorkbook.Sheets("BL") With sheetBL datCol = .Range(.Cells(14, .Columns.Count). _ End(xlToLeft).Address).Column If datCol > 248 Then MsgBox "これ以上データ追加できません。" Exit Sub End If For i = 4 To 248 Step 4 If .Cells(14, i).Value = "" Then .Range(.Cells(14, i), .Cells(22, i + 2)).Value _ = Sheets("測定結果").Range("G14:I22").Value Exit For End If Next i End With Set sheetBL = Nothing End Sub また、このプログラムを元にして、今度はG14:I14に入った値を、シート「まとめ」のC6を開始位置とし、C7、C8と今度は行ごとに値のみコピーをするプログラムに変更は可能でしょうか? よろしくお願いします。

  • VBA(売り、買い)

    以下のようにある条件で買いと売りのサインを求めたいのですが、買いのあとは必ず売りで、売りのあとは必ず買いにするにはどうしたらいいでしょうか?(買い増ししない) (例、2日に買いの条件になったので買いで、5日も買いの条件になったけれど前回(2日)が買いだったのでなにもしない。8日に売りの条件が出たので売り。のような) Dim i As long,a As Long,b As Long For i = 18 To 305 If ActiveSheet.Cells(i - 1, 4) > 20 And ActiveSheet.Cells(i, 4) < 20 Then a = "買い" If ActiveSheet.Cells(u(i - 1), 6) = "買い"Then ActiveSheet.Cells(i, 6) = a End If If ActiveSheet.Cells(i - 1, 4) < 80 And ActiveSheet.Cells(i, 4) > 80 Then b = "売り" ActiveSheet.Cells(i, 6) = b End If Next

  • VBAで教えてください。

    データがないときはExitSubしたいのですが、何処に記述すれば良いでしょうか? Sub 削除() Dim i As Long If MsgBox("データを削除します。よろしいですか?", vbYesNo) = vbYes Then Sheets("リスト").Select i = 5 Do Until i = 200 If Cells(i, 5).Value = Sheets("マスタ登録").Range("D5") Then Cells(i, 1).EntireRow.Delete End If i = i + 1 Loop Else Exit Sub End If End Sub

  • 【Excel VBA】ワークシートの表示(続き)

    すみません。 追記が出来なかったため、コードの続きをこちらに記載します。 For i = 1 To 12 If actsht = tmp(i) Then Flag = 1 Anser = MsgBox("翌月分シートを作成しますか?", vbYesNo + vbDefaultButton1, "確認") If Anser = vbYes Then ActiveSheet.Copy After:=ActiveSheet ActiveSheet.Name = tmp(i + 1) Sheets(actsht).Tab.ColorIndex = 2 Sheets(actsht).Range("B3").Value = Sheets("Sheet2").Range("A1").Value Sheets(actsht).Range("B4").Value = Sheets("Sheet2").Range("A2").Value ActiveSheet.Range("A2").Select Exit For ElseIf Anser = vbNo Then Exit For End If End If Next If Flag = O Then MsgBox ("新しいワークシートを作成出来ません。") End If If actsht = tmp(i) Then If Sheets(元データ).Visible = False Then Sheets(元データ).Visible = True End If End If End Sub

  • VBAでの質問

    お世話になります。 下記の記述で、「←」の矢印の記述で、 Cells.(5,2)がブランクでなければ、 「→」から進めたいのですが、 どの様に記述すれば宜しいでしょうか ご教示お願いします。 Sub 表記入() Dim Data As Range Dim i As Integer Dim j As Integer Dim k As Integer Set Data = Sheets("集計").Range("A2").CurrentRegion j = 16 k = 0 With Sheets("表") For i = 3 To Data.Rows.Count If Data.Cells(i, 51) <> "" Then .Cells(5, 2) = Data.Cells(i, 3)  ← .Cells(5, 7) = Data.Cells(i, 4) → .Cells(j, 2) = Data.Cells(i, 10) .Cells(j, 6) = Data.Cells(i, 11) & Data.Cells(i, 12) .Cells(j, 14) = Data.Cells(i, 51) Else End If k = k + 1 If k = 10 Then j = j + 18 k = 0 Else j = j + 1 End If End If Next i End With End Sub

  • エクセルVBA  どうしても動きません。

    お世話になります。 なかなか上達しない超初心者です。 ↓↓ですが、Activesheetにすると動くのに、シート名を元々存在するシート”実験"に指定すると動きません(データ内容はまったく同じで、A列に色んな名前が入っていて、重複しているとC列に重複と入力します)。 2日間試行錯誤したのですが、やっぱり動かず・・・ ちなみに、Activateにするとアクティブになるし、CurrentRegionも選択できるのに なんでうごかないんでしょうか・・・ 何卒ご指導くださいませ。よろしくお願いいたします!!!!!! Sub Test2() With Sheets("実験").Range("A1").CurrentRegion Dim i As Long Dim LastRow As Long LastRow = Range("A" & Rows.Count).End(xlUp).Row For i = 1 To LastRow If WorksheetFunction.CountIf(Range("A:A"), Cells(i, 1)) > 1 Then Cells(i, 3) = "重複" End If Next i End With End Sub Sheets("実験")をActivesheetに変えると別のシートがしっかり動いてくれます・・・が、なんとしてでも”実験”シートに動いていただきたいです・・・。

  • このVBAソースのどこが間違ってるか教えてください

    Dim csp As Integer 'ストップ Dim css As Integer 'ストップorスタート Sub Quest2() If css = 0 Then css = 1 Quest2a Else cstp = 1 css = 0 End If End Sub Sub Quest2a() Sheets("Sheet1").Select Range("B1:J10").Select Selection.Interior.ColorIndex = x1None Range("a1").Select cstp = 0 Do r = 1: c = 5 For i = 0 To 15 If i < 9 Then Cells(r, c).Interior.ColorIndex = x1None r = r + 1 If i < 5 Then c = c + 1 Else c = c - 1 End If Cells(r, c).Interior.ColorIndex = 3 Else Cells(r, c).Interior.ColorIndex = x1None r = r - 1 If i < 13 Then c = c - 1 Else c = c + 1 End If Cells().Interior.ColorIndex = 3 End If 'タイミング For tm1 = 1 To 1000: For tm2 = 1 To 100: Next If cstp = 1 Then Exit For End If Next DoEvents If cstp = 1 Then Exit For End If If r = 3 And c = 5 Then Cells(r, c).Interior.ColorIndex = x1None End If Next DoEvents If cstp = 1 Then Exit Do End If Loop Cells(10, 9) = Cells(r, c) Cells(10, 9).Interior.ColorIndex = 8 End Sub

専門家に質問してみよう