Excel VBA質問箱 IV

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

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


219 / 3841 ページ ←次へ | 前へ→

【78068】Re:指定したセルのフォントカラーの確認...
発言  β  - 16/3/26(土) 12:57 -

引用なし
パスワード
   ▼mjhwc152 さん:

たとえば 指定セルが A1 の場合。


Sub Test()
  Dim color As Variant
  
  color = Range("A1").Font.color
  
  If IsNull(color) Then
    MsgBox "文字ごとに文字色が異なっています"
  Else
    MsgBox "文字の色コードは " & color & " です"
  End If
  
End Sub
・ツリー全体表示

【78067】Re:イベント処理について
発言  β  - 16/3/26(土) 12:52 -

引用なし
パスワード
   ▼かず さん:

回答ではありません。

>7)キーがマッチする行や挿入先の行が風名などの場合は

風名 とは?

>サンプルコードの解説を補足します

これを見るために、井川さんの書式を購入しなければいけないのですか?
・ツリー全体表示

【78066】指定したセルのフォントカラーの確認方法...
質問  mjhwc152 E-MAIL  - 16/3/26(土) 12:43 -

引用なし
パスワード
   Microsoft Excel 2013 でマクロの初心者です。
指定セルに入力済の文字のフォントカラーを、マクロでの確認方法を教えて頂けないでしょうか。
・ツリー全体表示

【78065】Re:イベント処理について
回答  かず  - 16/3/26(土) 11:31 -

引用なし
パスワード
   ▼かず さん:

サンプルコードの解説を補足します

 では、1.'から順に見ていきましょう。
 まず、1行目でEventステートメントを使ってイベントを宣言しています。このクラスは
Rowslnsertというイベントを発行して、そのイベントプロシージヤは、CancelというBoolean d
の引数を参照渡しで受け取りますよ、といった宣言になります。
 CheckRowsInsertメソッドは、この後解説するタイマー処理によって繰り返し実行され、行
が挿入されたタイミングでイベントを発行するメソッドです。ここで重要なのは、Static変数
「myRow」が最終行を表すRangeオブジェクトへの参照を保持していることです。初めて実行
されるときだけは変数「myRow」が「Nothing」なので、その場合には最終行を表すRange オ
ブジェクトへの参照を格納するだけの処理を行いますが、2回目以降にはいよいよチェックを行
います。
 このチェックには、On Error Resume Nextステートメントを使って、実行時エラーを無視す
るようにしてから、変数「myRow」に参照が格納されているRangeオブジェクトの何らかのプ
ロパティを取得してみるのが簡単です。ここではRowプロパティを取得していますが他のプロ
パティでもかまいません。
 このとき、行が挿入されていれば最終行は存在しなくなっているのでエラーが発生します、
ですから、「エラーの発生=行が挿入された」と判断できるわけです。エラーの発生の有無は、
Err関数を使って参照を取得できるErrObjectオブジェクトのNumberプロパティで判断でき
ます。エラーが発生していなければNumberプロパティの値が「O」となるからです。
 そして、行が挿入されたと判断したらRaiseEventステートメントを使ってRowslnsertイベン
トを発行します。引数Cancelには変数[myCancel]を指定し、イペントプロシージヤによって、
変数.[myCancel」の値が「True」に変更される(引数Cancelに「True」が設定される)と、
ApplicationオブジェクトのUndoメソッドを使って、行挿入の操作を元に戻します。

 次に、2.のコードをご覧ください。これはタイマープロシージヤと呼ばれるプロシージヤで、
この後解説するWin32API関数のSetTimer関数の引数IpTimei'Funぺこ、このプロシージヤの
アドレスを指定すると、繰り返し非同期で実行されるようになります。
 宣言部については決まり事として覚えておいてください。ここで行っている処理は、
clsRowsInsertEventオブジェクトのCheckRowsInscrtメソッドを実行するといったものですI
clsRowsInsertEventオブジェクトへの参照は、3.のコードで定義しているThisWorkbookク
ラスのRowsInsertEventClassプロパティを使って取得します。

 最後に3.・のコードの要点をまとめます。
 まず、このブックモジュールでclsRowsInsertEventオブジェ列ヽが発行するイベントをハンド
ルするために、モジュールレベルのオブジェクト変数「mvRowsInsertEventClass」を、

 WithEventsキーワードを付けて、cIsRowsInsertEvent型で宣言します。
 そして、そのclsRowsInsertEventオブジェ列ヽのRowslnsertイペントプロシージャに、
行挿入時に実行する処理を記述します。ここでは、キャンセルするかどうかの問い合わせのみ
を行っています。
 タイマー処理の開始はブックのOpenイベントプロシージャで、終了はBeforeCloseイベント
ブロシージャで行います。
 タイマー処理を開始するのはWin32API関数のSetTimerで、引数HwndとnlDEventには0を、
uElapseにはタイマー処理を実行する問隔(ミリ秒)を、lpTimerFunc にはタイマープロシージャ
のアドレスを指定します。プロシージャのアドレスはAddressOf演算子を使って取得し
ます。なお、サンプルではnElapseに「O」を指定していますが、当然ですがOミリ秒ごとに処理
を繰り返すといった非現実的なことは不可能です。このような場合処理できる極めて微小な時間
単位で処理が繰り返されます。
 SetTimer関数の戻り値はタイマーIDと呼ばれる識別子で、
KillTimer関数のnIDEventに指定することでタイマー処理を終了できます。サンプルで、ブックの
BeforeCloseイベントプロシージャの処理に保存確認のロジックを内包しているのは、Beforecloose

イペントプロシージャの処理によってタイマー処理(イベント発行のための監視)を完了してから、
Excelの機能によって保存確認が行われた場合にキャンセルすると、イベントをハンドルできない状態
で開かれたままになるからです。
さて、3.のコードの最後で定義しているRowsInsertEventClassプロパティの内容はまったく
難しいものではありません。

モジュールレベル変数[my RowsInsertE vent Class]が「Nothing」であれば新たにインスタンスを
生成してから、その参照を返すプロパティです。しかし1つだけ重要なことがあります。
このようにして外部にclsRowsInsertEventオブジェクトヘの参照を返す(公開する)場合には、

clsRowsInsertEventクラスのInstancingがデフォルトのPrivate]のままではいけないからです。
このような場合には、あらかじめ[プロパティ]ウインドウを使ってInstancingを[PublicNotCreatable]
に設定しておきます。

ポイント
 タイマー処理中に実行時エラーが発生すると、Excelが即座に落ちてしまいます。万が一にもそのよう
なことがないように、絶対に実行時エラーが発生しない処理でない限り、必ずOn Error Resume Next
ステートメントを付けるようにしましょう。

--
・ツリー全体表示

【78064】イベント処理について
質問  かず  - 16/3/26(土) 11:09 -

引用なし
パスワード
   2つの表(リスト)を突き合わせる方法について有識者、
経験者の方のご意見をきかせてください。

1.業務要件
(1)建設プロジェク(=案件と呼ぶ。)の案件名、担当社、売上、利益
 などを1行にまとめて月次でメンテしています

(2)大元のマスタリストがあり、それを月に一回、10人の担当者に配布。
担当者は自分の担当案件の追加や、案件の売上や利益の変化を、配布
された表に記載して返信。

(3)各担当から返信されたリストを大元のマスタに反映させています

2.担当者が案件情報をリストに反映する際の記載ルール

▼(更新):
リストの各行に対し変更ががある場合、行の1列目に▼印をつける。

 削除は行削除ではなく、案件の進捗を示すセルを用意して、
 失注として表す。リストの行の削除は考慮不要。

★(挿入):
リストに対し、案件=行を追加する場合1列目に★印をつけて、行
ごと追加する


3.現状のマクロの仕様
1)マクロ本体のボタンを押す。
2)ダイアログが開いて、担当者の作成したリストのブックを指定する。
3)ダイアログが開いて、マスタのリストのブックを指定する

4)担当者のリストのシートを読み込み Find 文で1列目のセルを順に
読込む

5)1列目に▼を見つけたら、プロジェクトの区分、案件名、担当者を複合キー
として、マスタのリストからキーが合致する行を探す

6)1列目が★印の場合、その行の前の行を見る。
 前行の1列目のセルが空白か▼だったら、前行のキーで、マスタリストを検索
 し、挿入先の行を特定しその後ろに該当行をマスタリストのに挿入する。

7)キーがマッチする行や挿入先の行が風名などの場合は、マスタリストの一番後
 ろにその行を挿入し、1列目にエラー理由を書き込む。


4.問題
上の方法は、各担当者が作成する修正元リストのキーの一部の、
プロジェクト区分、案件名、担当者名 が変わるとマスタリストと突合わせがで
きません。

そこで次善の策として、キー項目を修正する場合は、修正元リストの1列目に▽
印を書き
同じ行の使われていない備考欄に、変更前のキーの項目を残しておき、マスター
のリスト
と突き合わで使っています。

この方法は、
・各担当者にとって ▼、★、▽の場合は、備考欄に元のキーを残す必要があるな
ど記載
 ルールが面倒らしく▼や★の取り違えや記載漏れ、▽の場合の備考欄の記載漏れ
が発生します。
・またキー項目を文字列としているため、変更元とマスタ側で文字の全角、半角
の違い等の場合も不一致が発せしやすいルールとなっています。

5.改善案

1.マスタ側で大本のマスタリスト作成時、従来のリストの外の右端余白に作業列
を追加
 1列目 そのリストを作成した日時のミリ秒単位でタイムスタンプを格納
 2列目 記号1文字 挿入I(最初はすべてI) or 変更C
     +リストの各行を識別するための項番(シーケンシャル)を記載
 3列目 行の修正箇所
 例 mm/dd/mm/ss△I,1

2.各担当者は、リストの行に変更を加えた場合のwork_sheet_Changeイベントプロシジャ内
 で以下を記載
 Private Sub WorkShhet_Change(ByVal Target As Range)
 If Not Application.Intersect(Target,Range(担当者リストの全領域)
 ’ここでTargetでを見てどこが参照されたか判定し
 ’タイムスタンプを作業列1、修正範囲を作業列3に書く
 End Sub

 a) 変更
 ・1列目に  ▼
 ・作業列1 タイムスタンプ
 ・作業列2 C+項番、
 ・作業列3 修正箇所のセル範囲

 例
 1列目 作業列1   作業列2 作業列3
 ▼   mm/dd/mm/ss C,10   $B$10,$C$10:$E$10,$F$10, $G$10 ...サイズ可変
         
 b) 挿入 自作のイベントを定義し、タイマーで監視し、イベントプロシージャで処理をする
  ・リストの1列目 ★格納
  ・作業列1 I+項番 
  2行追加の例

 1列目   作業列1   作業列2
 ★・・・  mm/dd/mm/ss I,10   ・・・元の行、挿入時のターゲット
 ★・・・  mm/dd/mm/ss I,10-1  ・・・挿入行1
 ★・・・  mm/dd/mm/ss I,10-2  ・・・挿入行2

 マスタ側から見て、担当者1、担当者2の挿入行が重なった時は以下。
 1列目  作業列1   作業列2
 ★・・・ 03/22/10/60 I,10
 ★・・・ 03/23/12/12 I,10-1  ・・・ 担当者1による挿入
 ★・・・ 03/23/50/13 I,10-1-1 ・・・ 担当者2による挿入
 ★・・・ 03/23/50/13 I,10-1-2 ・・・ 担当者2による挿入
 ★・・・ 03/23/12/12 I,10-2  ・・・ 担当者1による挿入 
 
 行挿入時ののイベントプロシジャの例は以下。
 「井川はるき VBA裏ワザ技大辞典」Sample31_1」のコード参照

 Private Sub myRowsInsertEventClass_RowsInsert(Cancel As Boolean)
  Cancel = MsgBox("行が挿入されました。" & vbCrLf _
    & "キャンセルしますか?", vbInformation Or vbYesNo) = vbYes
  ’★
 End Sub

 ★の部分に 担当者リストに行挿入がされた場合に
 1列目へ★記載や、作業列1、作業列2 作成の処理を書く

3.更新行処理 (1列目▼)
 作業列1、2を見る
 作業列1のタイムスタンプがマスタのタイムスタンプより新しい かつ
 作業列2の先頭文字がC
 作業列2の後半の、修正行の項番をキーとしてマスタのリストを検索し
 作業列3のセル範囲を修正する
 
 
4.挿入行処理 (1列目★)   
 作業列1のタイムスタンプがマスタのタイムスタンプより新しい かつ
 作業列2の先頭文字が Iの時 作業列2の, から枝番までの数字をキー
 にして、マスター側のリストを検索し、見つかったらそのうしろに枝番の
 ついた行を枝番の順序で挿入する
 

 注 井川はるき Excel VBA裏ワザ大辞典の TIPS 31 を参考にする
   添付 Sample031.xls では 行を挿入した時 キャンセルしますかという
   ウィンドウを表示させている

5.質問

 Q1 担当者リストには、イベントハンドラ処理を入れることによって悪影響
   を少なくする方法について教えてください

   例えばESCキーなどが押されマクロの実行=イベントの監視が行われなくなる
   だけでなく、担当者にとって意味不明のメッセージが出るなどを想定。

   こういった場合でもエラーが発生しました、ブックを閉じて再度開きなおして
   ください等のメッセージを出すか、どこかで イベント監視の機能を動かないように
   するApplication.EnableEvents = False を発行するよにしておき
   従来の処理を正常に実行できるようにしておきたいです

   どのような方法があるでしょうか

 Q2 Worksheet_Changeイベントは行の挿入時にも発生するようで
    自作するRowsInsertイベントと処理が重複して不具合がおきないか
    どのような方法があるでしょうか?
    

 よろしくお願い致します。

以上
・ツリー全体表示

【78063】Re:複数のシートで列の挿入を同期させたい
発言  β  - 16/3/18(金) 21:05 -

引用なし
パスワード
   ▼困っています さん:

>私一人が使うブックであれば、忘れずにシートのグループ化を行い
>作業をすれば問題ないのですが、別の人間も使用し、
>その者が度々グループ化を忘れ(そして行の挿入も忘れ)る為、今回の
>自動化を望んだ次第です。

ということなら、マクロ内で全シートをグループ化して処理。
最後にグループ化解除をしましょうか。

Sub そのメニュー()
  Dim RT As Long
  Dim w As Variant
  Dim sh As Worksheet
  Dim x As Long
  
  If ActiveSheet.Name <> "Sheet1" Then
    MsgBox "Sheet1 でのみ操作ができます"
    Exit Sub
  End If
  
  RT = Val(InputBox("1=行挿入" & Chr(10) & Chr(13) & _
            "2=行削除" & Chr(10) & Chr(13) & _
            "3=列挿入" & Chr(10) & Chr(13) & _
            "4=列削除" & Chr(10) & Chr(13) & _
            "5=キャンセル"))
            
  If RT <> 5 And RT <> 0 Then
  
    ReDim w(1 To Worksheets.Count)
    For x = 1 To Worksheets.Count
      w(x) = Worksheets(x).Name
    Next
    
    Worksheets(w).Select
    
     Select Case RT
    
      Case 1: Selection.Insert Shift:=xlDown
      Case 2: Selection.Delete Shift:=xlUp
      Case 3: Selection.Insert Shift:=xlToRight
      Case 4: Selection.Delete Shift:=xlToLeft
      
    End Select
    
    Sheets(1).Select
      
  End If
  
End Sub
・ツリー全体表示

【78062】Re:教えてください!かなり急いでいます。
発言  独覚  - 16/3/18(金) 19:59 -

引用なし
パスワード
   たぶん急ぎに間に合わなかったのだろうと判断して回答は削除しました。
・ツリー全体表示

【78061】複数のシートで列の挿入を同期させたい
質問  困っています  - 16/3/18(金) 19:26 -

引用なし
パスワード
   お世話になっております。
昨日1つ問題を解決して頂いたばかりで、誠に申し訳ないのですが、
もう1度お知恵を拝借できないでしょうか。

やりたいことは、複数のシート間での列の挿入の同期です。
(Sheet1に列を挿入したら、他のシートの同じ位置にも列を挿入したい。)
右クリックのメニューに項目を表示し、項目のクリックから
動作させたいと考えております。
右クリックのメニューに、項目の追加はできております。

重要な中身のコードは、Webで検索しよさそうなものを発見したので
そちらを拝借したいと思うのですが、コードが標準モジュール用ではなく、
「ThisWorkbook」に記述する用なのです…。

これを標準モジュール用に直したいのですが、
頭の部分を色々変更しただけでは直りませんでした。。。

拝借する予定のコードは以下の通りです。


Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Dim RT As Long
Dim mySh As Worksheet
Dim myRow As Long

Cancel = True

myRow = Target.Row

If Sh.Name <> "Sheet1" Then Exit Sub

RT = Val(InputBox("1=挿入" & Chr(10) & Chr(13) & _
"2=削除" & Chr(10) & Chr(13) & _
"3=キャンセル"))

If RT <> 3 And RT <> 0 Then
For Each mySh In Worksheets
mySh.Select
Rows(myRow).Select
Select Case RT
Case 1
Selection.Insert Shift:=xlDown
Case 2
Selection.Delete Shift:=xlUp
Case 3
End Select
Next mySh
End If
Sh.Select
End Sub


参考書と見比べておりますが、実は大半の意味を理解できずにおります…。
少し手直しする程度では動きませんか?
もし大幅な変更が必要であれば、あきらめたいと思います。
(教えて頂くにも、あまりにも無知で申し訳ないので。。。)

私一人が使うブックであれば、忘れずにシートのグループ化を行い
作業をすれば問題ないのですが、別の人間も使用し、
その者が度々グループ化を忘れ(そして行の挿入も忘れ)る為、今回の
自動化を望んだ次第です。


以上、皆様大変お忙しいかと存じますが、
何卒ご助力の程、よろしくお願い致します。
・ツリー全体表示

【78060】Re:指定範囲内の行、及び列を、指定数お...
お礼  困っています  - 16/3/18(金) 16:19 -

引用なし
パスワード
   ▼β さん:

> どうしても 1 なら 1行おき(つまり 2行ブロック)、2 なら 2行おきということであれば
>
> If n = 0 Then Exit Sub
>
> この下に
>
> n = n + 1
>
> をいれてください。


こ、こんな大変なコードになるだなんて・・・!
ご提案頂いたコードに、上記の「n = n + 1」を入れることで、
私のやりたいことが完璧にできました。
本当に本当に感謝申し上げます。
私の浅い知識では、Web上の情報と書籍の情報を組み合わせても
早々たどり着けるものではないと思いました。

貴重なお時間を割いて頂き、今一度感謝申し上げます。
ありがとうございました。
・ツリー全体表示

【78059】Re:指定範囲内の行、及び列を、指定数お...
発言  β  - 16/3/17(木) 22:54 -

引用なし
パスワード
   ▼困っています さん:

アップしたコードは、たとえば 3 といれた場合、行の表示処理だとすると
3行1ブロックで ブロックの1行目が表示、2,3行目が非表示というロジックにしました。
質問を読み返してみると、1 なら 1行おき ということですから、提示要件とアップしたコードとは
整合性がとれていませんが、まぁ、そのあたりは、コードで対処している規則で
ためしてください。

どうしても 1 なら 1行おき(つまり 2行ブロック)、2 なら 2行おきということであれば

If n = 0 Then Exit Sub

この下に

n = n + 1

をいれてください。
・ツリー全体表示

【78058】Re:指定範囲内の行、及び列を、指定数お...
発言  β  - 16/3/17(木) 17:34 -

引用なし
パスワード
   ▼困っています さん:

これだけの選択肢があるわけですから、ユーザーフォームで条件をセット、
あるいはシート上のオプションボタン等で条件をセットして実行するのが
わかりやすいとは思いますが、以下は遊びです。
対象領域もマクロ内で選択させます。

Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function SetWinEventHook Lib "user32" _
    (ByVal eventMin As Long, ByVal eventMax As Long, _
    ByVal hmodWinEventProc As Long, _
    ByVal pfnWinEventProc As Long, _
    ByVal idProcess As Long, ByVal idThread As Long, _
    ByVal dwFlags As Long) As Long
Private Declare Function UnhookWinEvent Lib "user32" _
    (ByVal hWinEventHook As Long) As Long
Const WINEVENT_OUTOFCONTEXT = &H0
Const EVENT_SYSTEM_ALERT = &H2
Private Declare Function SetDlgItemText Lib "user32" _
    Alias "SetDlgItemTextA" _
    (ByVal hDlg As Long, ByVal nIDDlgItem As Long, _
    ByVal lpString As String) As Long


Sub Test()
  Dim ans As Variant
  Dim ansStr As String
  Dim disp As VbMsgBoxResult
  Dim DoRow As VbMsgBoxResult
  Dim n As Long
  Dim r As Range
  Dim msg As String
  Dim x As Long
  Dim a As Range
  Dim func As Boolean
  
  On Error Resume Next
  Set r = Application.InputBox("処理する領域を選択してください", Type:=8)
  On Error GoTo 0
  
  If r Is Nothing Then Exit Sub
  
  SetWinEventHook EVENT_SYSTEM_ALERT, EVENT_SYSTEM_ALERT, _
          0, AddressOf WinEventProc1, 0, _
          GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT
  disp = MsgBox("表示/非表示どちらにしますか?", vbYesNoCancel Or vbQuestion)
  
  If disp = vbCancel Then Exit Sub
  
  If disp = vbYes Then
    msg = "表示"
  Else
    msg = "非表示"
  End If
  
  SetWinEventHook EVENT_SYSTEM_ALERT, EVENT_SYSTEM_ALERT, _
          0, AddressOf WinEventProc2, 0, _
          GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT
  DoRow = MsgBox(msg & " が選ばれました" & vbLf & _
    "行/列どちらにしますか?", vbYesNoCancel Or vbQuestion)
  
  If DoRow = vbCancel Then Exit Sub
  
  If DoRow = vbYes Then
    msg = msg & "/行 "
  Else
    msg = msg & "/列 "
  End If
  
  n = Application.InputBox(msg & "が選ばれました" & vbLf & "何行おきに処理しますか?", Type:=1)
  
  If n = 0 Then Exit Sub
  
  If disp = vbYes Then func = True
  
  If DoRow = vbYes Then
    For x = 1 To r.Rows.Count Step n
      r.Rows(x).EntireRow.Hidden = Not func
      r.Rows(x).Offset(1).Resize(n - 1).EntireRow.Hidden = func
    Next
  Else
    For x = 1 To r.Columns.Count Step n
      r.Columns(x).EntireColumn.Hidden = Not func
      r.Columns(x).Offset(, 1).Resize(, n - 1).EntireColumn.Hidden = func
    Next
  End If
  
End Sub

Private Sub WinEventProc1( _
      ByVal hEvent As Long, ByVal dwEvent As Long, _
      ByVal hwndMsg As Long, ByVal idObject As Long, _
      ByVal idChild As Long, ByVal idThread As Long, _
      ByVal dwmsEventTime As Long)
  UnhookWinEvent hEvent
  SetDlgItemText hwndMsg, vbYes, "表示"
  SetDlgItemText hwndMsg, vbNo, "非表示"
  SetDlgItemText hwndMsg, vbCancel, "や〜めた"
End Sub

Private Sub WinEventProc2( _
      ByVal hEvent As Long, ByVal dwEvent As Long, _
      ByVal hwndMsg As Long, ByVal idObject As Long, _
      ByVal idChild As Long, ByVal idThread As Long, _
      ByVal dwmsEventTime As Long)
  UnhookWinEvent hEvent
  SetDlgItemText hwndMsg, vbYes, "行"
  SetDlgItemText hwndMsg, vbNo, "列"
  SetDlgItemText hwndMsg, vbCancel, "や〜めた"
End Sub
・ツリー全体表示

【78056】Re:教えてください!かなり急いでいます。
発言  β  - 16/3/17(木) 16:07 -

引用なし
パスワード
   ▼やま さん:

・Cellsのなかの YA ですけど、別のところで、ここには 数値が入っているのですね?
・フォーマット という変数、シートオブジェクトですけど、これもどこかでセットされているんですね?

等々 わからないところもありますが、フォーマットはシートオブジェクトです。
シートオブジェクトというのは、
ワークブックオブジェクト.シートオブジェクト という内容になっています。

ですから、最初の フォーマット.Cells(YA, 1) は OKになります。
でも、2回目に使われている Workbooks("外注入力システム").フォーマット.Cells(YA, 5)

これは

ワークブックオブジェクト.ワークブックオブジェクト.シートオブジェクト

という記述になります。

そうすると、ワークブックオブジェクトの配下にワークブックオブジェクトはないので
エラーになります。
・ツリー全体表示

【78055】Re:教えてください!かなり急いでいます。
回答  やま  - 16/3/17(木) 16:00 -

引用なし
パスワード
   ▼独覚 さん:
>▼やま さん:
>フォーマットってどこでどのように設定してあるの?

変数に入れこんであります。
フォーマット=sheets(”フォーマット”)
・ツリー全体表示

【78054】Re:教えてください!かなり急いでいます。
発言  独覚  - 16/3/17(木) 15:53 -

引用なし
パスワード
   ▼やま さん:
フォーマットってどこでどのように設定してあるの?
・ツリー全体表示

【78053】指定範囲内の行、及び列を、指定数おきに...
質問  困っています  - 16/3/17(木) 14:41 -

引用なし
パスワード
   初めまして。自力ではどうにもできなかったため、
お知恵をお貸し頂けないでしょうか。

Excelにて、まず範囲を選択し、その範囲内において、
飛び数を指定し、そのとび数おきに列を選択する、
または非表示にすることはできないでしょうか。

例えば、

A列からZ列を選択し、マクロを実行すると、
「飛び数を指定して下さい:」と表示され、
1を入れたら、A列からZ列の間を1列おきに選択(ないし非表示)にする。
2を入れたら、A列からZ列の間を2列おきに選択(ないし非表示)にする。

といった形です。

範囲は常にA列からZ列ではないため、決め打ちでVBAに指定はできません。
(都度取得したい)

出来れば行にも対応できると助かります。
列用と行用でマクロが2つになっても構いません。
(1つになると万々歳ではありますが・・・!)

以上、何卒ご助力の程、よろしくお願い致します。
・ツリー全体表示

【78052】教えてください!かなり急いでいます。
質問  やま  - 16/3/17(木) 13:25 -

引用なし
パスワード
   If フォーマット.Cells(YA, 1) = "23008" Then
都度在庫 = Application.WorksheetFunction.VLookup(Workbooks("外注入力システム").フォーマット.Cells(YA, 5), Workbooks("外注価格表最新.xlsx").Sheets("クツザワ新").Range("B2:Z1000"), 8, False)

オブジェクトは、このプロパティまたはメゾットをサポートしていませんが出てきます。
どうすればいいのでしょうか?
・ツリー全体表示

【78051】Re:別ファイルにあるセル範囲を配列に格...
お礼  ayu  - 16/3/15(火) 9:13 -

引用なし
パスワード
   ▼β さん:
こんなに早くお返事を頂けるとは思っていませんでした。
おかげ様で、きれいにデータを並び替えることができました。正直、配列準備のところはぱっと見ただけではよく分かりませんが、じっくり調べて理解したいと思います。何度も貴重なお時間を割いて頂き、本当にありがとうございました!!m(_ _)m
>▼ayu さん:
>
>以下、試してください。
>
>Sub Sample3()
>  Dim shF As Worksheet
>  Dim shT As Worksheet
>  Dim v As Variant
>  Dim w As Variant
>  Dim x As Long
>  Dim y As Long
>  Dim i As Long
>  Dim j As Long
>  
>  Application.ScreenUpdating = False '処理中の画面の動きを隠す
>  Set shT = ThisWorkbook.Sheets("フォーマット")                          '★
>  Set shF = Workbooks.Open(ThisWorkbook.Path & "\元のブック.xlsx").Sheets("該当のシート名")    '★
>  
>  With shF.Range("A1").CurrentRegion '元シートの表領域
>    '転記用配列準備(厳密には、こんなに大きくなくてもいいですが)
>    ReDim v(1 To .Rows.Count, 1 To .Columns.Count * 2)
>    For i = 2 To .Rows.Count Step 2
>      If WorksheetFunction.CountIf(.Rows(i), ">0") > 0 Then 'すべて 0 なら対象外
>        y = y + 1  '転記行
>        x = 0    '転記列
>        For j = 1 To .Columns.Count
>          If .Cells(i, j) > 0 Then
>            x = x + 1
>            v(y, x) = .Cells(i - 1, j).Value
>            v(y, x + 1) = .Cells(i, j).Value
>            x = x + 1
>          End If
>        Next
>      End If
>    Next
>  End With
>  
>  shF.Parent.Close False '元ブックを閉じる
>  '結果を一括転記
>  shT.Cells.ClearContents
>  shT.Range("A1").Resize(y, UBound(v, 2)) = v
>
>End Sub
・ツリー全体表示

【78050】Re:別ファイルにあるセル範囲を配列に格...
発言  β  - 16/3/14(月) 16:19 -

引用なし
パスワード
   ▼ayu さん:

以下、試してください。

Sub Sample3()
  Dim shF As Worksheet
  Dim shT As Worksheet
  Dim v As Variant
  Dim w As Variant
  Dim x As Long
  Dim y As Long
  Dim i As Long
  Dim j As Long
  
  Application.ScreenUpdating = False '処理中の画面の動きを隠す
  Set shT = ThisWorkbook.Sheets("フォーマット")                          '★
  Set shF = Workbooks.Open(ThisWorkbook.Path & "\元のブック.xlsx").Sheets("該当のシート名")    '★
  
  With shF.Range("A1").CurrentRegion '元シートの表領域
    '転記用配列準備(厳密には、こんなに大きくなくてもいいですが)
    ReDim v(1 To .Rows.Count, 1 To .Columns.Count * 2)
    For i = 2 To .Rows.Count Step 2
      If WorksheetFunction.CountIf(.Rows(i), ">0") > 0 Then 'すべて 0 なら対象外
        y = y + 1  '転記行
        x = 0    '転記列
        For j = 1 To .Columns.Count
          If .Cells(i, j) > 0 Then
            x = x + 1
            v(y, x) = .Cells(i - 1, j).Value
            v(y, x + 1) = .Cells(i, j).Value
            x = x + 1
          End If
        Next
      End If
    Next
  End With
  
  shF.Parent.Close False '元ブックを閉じる
  '結果を一括転記
  shT.Cells.ClearContents
  shT.Range("A1").Resize(y, UBound(v, 2)) = v

End Sub
・ツリー全体表示

【78049】Re:別ファイルにあるセル範囲を配列に格...
発言  β  - 16/3/14(月) 9:30 -

引用なし
パスワード
   ▼ayu さん:

おそらく、Sample2の方式(外部参照数式方式)をもとにトライされているんですかね?
数式で処理すようとすると、同じブックにあっても、左詰め、上詰めが必要で
数式エキスパートさんなら 超難解な数式を組み立て(もしかしたら配列数式)ることも可能かとも思いますが
βには、とっても無理です。
逆に、ayuさんが、同じブックに元シートがあるとすれば、ひっぱってくる数式を書くことができるなら
それを教えてください。
その数式を使ったコードをβが書くことはできますので。

むしろ、Sample方式、つまりブックを開いて、処理する方式が、エクセルの持つ優れた機能を
使うこともできますし、コードもわかりやすいと思います。

で、とりあえず Sample方式で、コードを書きますが、時間がなかなかとれないので
明日、あるいは明後日になるかもしれません。
・ツリー全体表示

【78048】Re:別ファイルにあるセル範囲を配列に格...
質問  ayu  - 16/3/14(月) 6:25 -

引用なし
パスワード
   ▼β さん:
お世話になります。この前教えて頂いた事を元にやりたい事を色々試しているのですが、詰まってしまいましたので、再度質問させて頂きます。
教えて頂いた事を基に、別シートから項目名と合計数を抽出し、転記先のシートに下記のようにするとこるまではできました。このように奇数行が項目名で、偶数行が該当項目の合計数になっています。項目数は一定しておらず下記に表示してるより多い行もあります。

    A列    B列   C列  D列   E列   F列   G列    H列
1行目 S-Trim  M-Trim  SC-S  SC-ML Under12 Point   N/A    
2行目 32    10    3    7   0    0     0    
3行目 C-Re/VS  C-S   C-M  C-Semi C-L   C-SLong  N/A    
4行目 0     1    0    0   0    0     0    
5行目 HL-Half  HL-Full  HL-Point   N/A               
6行目 0     0    0    0                
7行目 STP-Re  STP-S  STP-M STP-Semi STP-L STP-SLong STP-Bang N/A
8行目 0     0    0    0   0    0     0    0  
9行目 BL-Dry   TR   Iron  N/A                
10行目 0     0    0    0                
11行目 C-Eyeblow Beard  Iron  Rinse  Shampoo Bang   N/A  
12行目 0     0    0    0   0    3     0    
この下にも何行か続きます。

上記の表から印刷用のフォーマットに数字をコピーしたいのですが、そのフォーマットが
メニュー名|数|メニュー名|数|メニュー名|数|メニュー名|数|メニュー名|数
のようになっており、この行が9行ありまして、上記のメニューと合計セットも9つあります。
この印刷用のフォーマットに合計数が0以上のメニュー名と合計数をコピーしたいのですが、その方法が分からず詰まっています。

例えば上の例でいくと下記のように表示したいです。(合計数が0のメニューは無視)

    A列  B列  C列  D列 E列 F列 G列 H列
1行目 S-Trim  32  M-Trim 10  SC-S 3  SC-ML 7
2行目 C-S    1
3行目 Shampoo  3
4行目 Bang    3

このようにするべく色々模索しておりますが、なかなか上手くいきません。お時間のある時にでも何かヒントでも頂けたら大変ありがたいです。
何度もすみませんが、宜しくご教示お願いいたします。

>▼ayu さん:
>
>>左側で指定したセル範囲に右側のA2のFormulaをコピーし、
>>右側のセル範囲の値を左側で設定したシートのセル範囲にコピーする
>>ということであってますでしょうか?
>
>A2のFormula というのが、ちょっと変ですけど、以下のようなことです。
>
>たとえばステップ実行はご存じでしょうか。
>VBE画面で、Sample2 の任意のところをクリックしてF8 を押します。
>最初は Sub Sample2() が黄色くハイライトされます。
>で、そのまま F8 を押していきます。
>  shT.Range("A1:F2").Value = shT.Range("A1:F2").Value
>ここが黄色くなったら F8を押さず、マクロブックの "転記先のシート名" をみてください。
>この A1:F2 に、元ブックを参照する参照式が入っています。
>
>式と表示されている値を確認したら、VBE画面に戻り End Sub まで F8 を押していって下さい。
>
>Sample がうまくいったということですから、同じ環境(フォルダやブック名やシート名)で実行すれば
>シートに参照式がセットされ、そこで参照している値がシートに表示されているはずなんですが。
・ツリー全体表示

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