(1)作業環境
Windows 7 Professional SP1
Intel(R) Core(TM) i3­3240 CPU @ 3.40GHz 4.00GB
32ビットオペレーティングシステム
Microsoft Office Standard 2010
Excel ver.14


(2)やりたいこと
3つのファイルのzipファイルを同じフォルダに作成したい
  C:\temp\a.txt
  C:\temp\b.txt
  C:\temp\c.txt
  から
  C:\temp\d.zip
  を作りたい。


(3)状況
下記サイトを参照しましたが知識不足で正確にわからないのと、『本当にこんなに長いコードが必要なのか?』と疑問に思っています。

 参考①VBAでZIP圧縮する。
 http://scripting.cocolog-nifty.com/blog/2007/11/ …

 参考②ファイル/フォルダをzipファイルに圧縮
 http://qiita.com/kou_tana77/items/72346c69107fab …

定義、ループ、分岐など基本的なことは分かっています。
APIやFSOなども詳しくはないですが、知っています。
たとえば①の「fso.*******」、「Shell.*******」などの、*******が分かりません。


(4)質問事項
余計なものは除いて必要最低限のコードだけにするとどのようになるかしりたいです。
※エラー処理などに関しては使用環境にあわせて作成します。


ご存じの方ご教示くださいm(_ _)m

質問者からの補足コメント

  • ありがとうございます。
    ここに掲載するときは見やすいように外しちゃいましたが、実際は上記の待つ作業ないとエラーになりました。

    回答いただいたマクロをもとに実用箇所にアレンジすることができました。
    ありがとうございました^_^

    No.2の回答に寄せられた補足コメントです。 補足日時:2016/01/26 20:23

このQ&Aに関連する最新のQ&A

A 回答 (2件)

こんな感じでしょうか?


・既に圧縮書庫ファイルが存在する場合は上書きされます。
・指定した被圧縮ファイルが存在しなかった場合はハングアップします。

-----------------------------
Sub MakeZip()
Dim sfo As Object, app As Object
Set sfo = CreateObject("Scripting.FileSystemObject")
Set app = CreateObject("Shell.Application")

Dim zipFolder As Object
Dim file As Variant
Dim count As Long

Const zipFile = "C:\excel\圧縮.zip" '圧縮書庫ファイルの絶対パス
Dim files As Variant
files = Array("C:\excel\あ.txt" _
, "C:\excel\い.txt" _
, "C:\excel\う.txt") ' 圧縮するファイルの絶対パス

'空のzipファイルを作成する
With sfo.CreateTextFile(zipFile, True)
.Write "PK" & Chr(5) & Chr(6) & String(18, 0)
.Close
End With
Set zipFolder = app.Namespace(sfo.GetAbsolutePathName(zipFile))

'zipファイルに圧縮対象のファイルをコピーする
count = 0
For Each file In files
count = count + 1
zipFolder.CopyHere (sfo.GetAbsolutePathName(CStr(file)))
'このファイルのコピーが終わるまで待つ。
Do Until zipFolder.Items().count = count
Application.Wait Now + TimeSerial(0, 0, 1)
Loop
Next
Set sfo = Nothing
Set app = Nothing
Set zipFolder = Nothing
End Sub
    • good
    • 1
この回答へのお礼

ありがとうございます。
必要な分のみを書き出すと、
-----------------------------
 '空のzipファイルを作成する
 With sfo.CreateTextFile("C:\temp\d.zip", True)
  .Write "PK" & Chr(5) & Chr(6) & String(18, 0)
  .Close
 End With
 Set zip = app.Namespace(sfo.GetAbsolutePathName("C:\temp\d.zip"))
 '作成したzipファイルにファイルをコピー
 zip.CopyHere (sfo.GetAbsolutePathName("C:\temp\a.txt"))
 zip.CopyHere (sfo.GetAbsolutePathName("C:\temp\b.txt"))
 zip.CopyHere (sfo.GetAbsolutePathName("C:\temp\c.txt"))
-----------------------------
ということですね!
とてもシンプルになり、これでいろいろアレンジして使用できます。
ベストアンサーにしたいのですが、ついでに
.Write "PK" & Chr(5) & Chr(6) & String(18, 0)
は何をしているのかも教えていただけないでしょうか?

お礼日時:2016/01/26 13:05

No.1です。



> .Write "PK" & Chr(5) & Chr(6) & String(18, 0)
> は何をしているのかも教えていただけないでしょうか?

ZIPファイルの終端レコードを示すデータを新規作成したファイルに書き込んでいます。
これにより作成したファイルが「空のZIPファイル」と認識されるようになります。


あと気になったのですが
お礼をいただいた中のソースにファイル一つずつのコピー(圧縮)終了を待つ記述(下記)がありません。
この記述が無いとZIPファイルに複数の被圧縮ファイルを追加する際に取りこぼしが生じる可能性があります。


count = 0
For Each file In files
count = count + 1
zipFolder.CopyHere (sfo.GetAbsolutePathName(CStr(file)))
'このファイルのコピーが終わるまで待つ。
Do Until zipFolder.Items().count = count
Application.Wait Now + TimeSerial(0, 0, 1)
Loop
Next
この回答への補足あり
    • good
    • 2
この回答へのお礼

今携帯から投稿していて、サイトがかなり使いづらく補足というところに記入してしまいました。

本当はここに記載する内容でした。
ありがとうございました。、

お礼日時:2016/01/26 20:26

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVBAでオブジェクト変数にsetしたシートがactiveかどうかを調べるには?

標準モジュールの冒頭でワークシート用のオブジェクト変数を確保し、
あるタイミングで、あるシートをそのオブジェクト変数にSetしています。

で、そのシートに値をセットするときに、そのシートがActiveだった場合だけやりたい処理があるのですが、Setしてあるオブジェクト変数だけを見てそのシートがActiveか否かを判断する方法って、あるのでしょうか。

コード例)
Private oSheetA as Worksheet

Sub SetSheet(sName as String)
  Set oSheetA = worksheets(sName)
End Sub

Sub SetValue(nValue as integer)
  xxxxxx ←ここでoSheetAがActiveならやりたいことがある。
  oSheetA.Cells(nRow, nCol) = cValue
End Sub

具体的には、複数のBookを開いている状態で、Activeシートが何であるかはオペレータの操作次第なので固定化できない状態で、SetValueが呼び出されたとき、oSheetAがActiveだったら、値をセットするセルが見えるようにセルをActivateかスクロールさせたいんです。

標準モジュールの冒頭でワークシート用のオブジェクト変数を確保し、
あるタイミングで、あるシートをそのオブジェクト変数にSetしています。

で、そのシートに値をセットするときに、そのシートがActiveだった場合だけやりたい処理があるのですが、Setしてあるオブジェクト変数だけを見てそのシートがActiveか否かを判断する方法って、あるのでしょうか。

コード例)
Private oSheetA as Worksheet

Sub SetSheet(sName as String)
  Set oSheetA = worksheets(sName)
End Sub

Sub SetValue(nVa...続きを読む

Aベストアンサー

Option Explicit

Private oSheetA As Worksheet

Sub SetSheet(sName As String)
Set oSheetA = Worksheets(sName)
End Sub

Sub SetValue(nValue As Integer)
If oSheetA Is ActiveSheet Then
MsgBox ("hoge")
End If
oSheetA.Cells(1, 1) = nValue
End Sub

Sub Main()
SetSheet ("Sheet1")
SetValue (5)
End Sub

'実行できるようにソースは変更していますが,
'こんな感じでIs演算子で同じオブジェクトか比較してみるってのはどうでしょう?

QZIP内の特定のファイルのみ抽出してZIP作成

ZIPファイル内の特定のファイルのみ抽出してZIPファイルを作成
したいのですが、パイプ等を使ってうまくできないでしょうか?

次のようにコマンドをいくつかあわせればとりあえず出来るのですが…
mkdir temp
unzip src.zip *.jpg -d temp
cd temp
zip -m ..\dst.zip *

もっとよい方法をご存知の方がいましたらご教授願います。

次のようにも試してみたのですが、うまくいきませんでした。
unzip -p src.zip *.jpg | zip dst.zip -

OSはWindowsXPです。
ZIPプログラムは必要であれば特定のZIPプログラムを
使用してもいいです。

Aベストアンサー

ANo.1 です。
そうですね。簡単なコマンドですむ方法はむずかしいかもしれませんね。
それでは、思いついたことをいくつか。

(1) zip 内のファイルを削除する方法の場合。
新しい zip ファイルを 3 個つくるなら、3 個以上のコマンドが必要でしょう。

copy src.zip 1.zip & zip -d 1.zip "*" -x "?.jpg" "??.jpg" "???.jpg"
copy src.zip 1000.zip & zip -d 1000.zip "*" -x "1???.jpg"
copy src.zip 2000.zip & zip -d 2000.zip "*" -x "2???.jpg"

上の 3 行を 1 行につないでもよいのでしょうが、ややこしくなるだけでしょう。
ファイル名が簡単なワイルドカードで表せる場合は、これでどうでしょうか。

(2) *.jpg のファイル名が簡単なワイルドカードで指定できない場合。
(たとえば数字といっしょにアルファベットが混じるファイル名があって、それは zip ファイルにしたくないとか)
ファイル名がいろいろあって簡単に指定できない場合は、ファイル名のリストを作っておくのがわかりやすいでしょう。
ファイル名がわからないときは
zipinfo -1 src.zip "1???.jpg" > 1000.lst
などとしていったんリストを作って、余計なファイルが混じるならあとで編集するなどの手間が必要かもしれません。
そのうえで、unzip でひとつずつ展開して、そのたびに zip でアーカイブに加えていくとかは、どうでしょう。

for /f %i in (dst.lst) do (
unzip src.zip %i
zip -m dst.zip %i
)

バッチファイルにして、dst のところを 1 とか 1000 とか 2000 とかのコマンドライン・パラメータで与えるのもいいかもしれません。
ファイル名の番号に規則性があるならリストファイルにしないで、
for /l %i in (1 1 999)
などと、連続した番号を生成するのもありかなと思います。

ANo.1 です。
そうですね。簡単なコマンドですむ方法はむずかしいかもしれませんね。
それでは、思いついたことをいくつか。

(1) zip 内のファイルを削除する方法の場合。
新しい zip ファイルを 3 個つくるなら、3 個以上のコマンドが必要でしょう。

copy src.zip 1.zip & zip -d 1.zip "*" -x "?.jpg" "??.jpg" "???.jpg"
copy src.zip 1000.zip & zip -d 1000.zip "*" -x "1???.jpg"
copy src.zip 2000.zip & zip -d 2000.zip "*" -x "2???.jpg"

上の 3 行を 1 行につないでもよいのでしょうが、...続きを読む

QExcel: SetステートメントでRangeオブジェクトに名前付きセルを指定したい

Excel VBAです。
RangeオブジェクトにSetステートメントで名前付きセルを指定したのですが、結果、RangeオブジェクトはEmpty値になってしまいます。名前付きではない別のセルでやってみるとうまくいきます。

Dim sSheet as Worksheet
Dim wRange as Range

Worksheets("Sheet1").Select

【失敗する例:名前付きセルを指定】
Set wRange=Range("c_ControlNo")

【うまくいく例:セルA1を指定】
Set wRange=Range("A1")

名前付きセルは指定できないなんてことはない、と思うのですが、どこがおかしいのでしょうか?
アドバイスをお願いします。

Aベストアンサー

Set wRange = Names.Item("c_ControlNo").RefersToRange

と指定します.
必要であれば,Namesプロパティの前にActiveWorkbook等を付加してください.

基本的に名前付きのセルはNameオブジェクトを経由して処理します.

QPythonでZIP中のZIPを操作する方法

【PythonでZIPファイル中のZIPファイルを操作したい】

PythonでZIP内のZIPを再帰的に探して操作したいと考えています。
スクリプトを書いてみたのですが、どうもうまくいきません。
どなたかマズところをご教示いただけないでしょうか?

以下のような構造のデータファイルを用意しました。
  SampleZip1.zip
    Sample1.txt
    Sample2.txt
    SampleZip1-1.zip
      Sample1-1-1.txt
      Sample1-1-2.txt
    SampleZip1-2.zip
      Sample1-2-1.txt
      Sample1-2-2.txt

以下がテストスクリプトです。
  import zipfile
  
  def listZipFile( fileName, indent ) :
  if not zipfile.is_zipfile( fileName ) :
    print( "not zip" + indent + fileName )
  return
  
  print( "zip" + indent + fileName )
  
  zip = zipfile.ZipFile( fileName, 'r' )
  
  for f in zip.namelist():
    listZipFile( f, "¥t"+ indent )
  
  zip.close()
  
  zipFileName = 'SampleZip1.zip'
  listZipFile( zipFileName, "¥t" )

が、結果は以下の通りで、ZIPの中のZIPをZIPファイルと判定してくれないみたいです。
  >findZip.py
  zip SampleZip1.zip
  not zip SampleZip1-2.zip
  not zip Sample1.txt
  not zip Sample2.txt
  not zip SampleZip1-1.zip

ZIPファイル中のファイルに対してzipfile.ZipFile()を使うのは無理があるのかなぁ?
一時ファイルにでもいったん出さないとダメ?
などと想像しているのですが・・・

どなたかよろしくお願いいたします。

【PythonでZIPファイル中のZIPファイルを操作したい】

PythonでZIP内のZIPを再帰的に探して操作したいと考えています。
スクリプトを書いてみたのですが、どうもうまくいきません。
どなたかマズところをご教示いただけないでしょうか?

以下のような構造のデータファイルを用意しました。
  SampleZip1.zip
    Sample1.txt
    Sample2.txt
    SampleZip1-1.zip
      Sample1-1-1.txt
      Sample1-1-2.txt
    SampleZip1-2.zip
      Sample1-2-1.txt
      S...続きを読む

Aベストアンサー

このサイトでは、連続する空白は1つにまとめられ、タブ文字は削られます。
Pythonではインデントが重要な役目を持っているので、全角空白を使うとか、別な文字(^だの_だの)で代りにするとしましょう。

> for f in zip.namelist():
で取り出せるfは、ZIPの中での一覧での名前です。実際にそのファイルがファイルシステム上に存在するわけではないし、その「ZIp内のファイル」にアクセスするために「ファイルのように振舞うオブジェクト」を返すわけでもありません。isZipfileで失敗するのは当然でしょう。

zipfileのマニュアルを読んでみると
read(ZIP内の名前)
でバイト列として取り出せるようなので、
fp=StringIO.StriingIO(zip.read(f))
などとファイル風オブジェクトにして
    listZipFile( fp, "¥t"+ indent )
とするのはどうでしょう。

QVBAで既に開いている別アプリケーションのオブジェクトを得る

 VBAで別のアプリケーションにアクセスするには、CreateObject関数を使ってアプリケーションのオブジェクトを作るようにすると思います。例えば、ワード文書にアクセスするなら次の構文になると思います。
  Set appWord = CreateObject("Word.Application")
  appWord.Visible = True
 しかしこれだと新しいワード文書を作ったり、既存のワードファイルを開いて扱うことしかできません。GetObject関数を用いても同様のようです。既に別ウィンドウで開いているワード文書があって、そこへアクセスするにはどうしたらよいのでしょうか。
 また、同じアプリで複数のファイルを開いている場合には、どうやって目的のファイルへのオブジェクトを得るのでしょうか。(ファイル名などを参照して判断?)

Aベストアンサー

Internet Explorerで開いているWindowを取得することはできますよ。

そのためには、まず開いているWindowを順番に取得し、それがInternet Explorerならばそれをオブジェクトに代入し、ひとつもIEウィンドウが存在しない場合は新規作成(CreateObject)すればいいのです。
Windowを取得するにはShell.Applicationというのを使います。

Dim ObjIE As Object
Dim ObjShell As Object
Dim ObjWindow As Object
Dim WinExist As Boolean

WinExist = False
Set ObjShell = CreateObject("Shell.Application")
For Each ObjWindow In ObjShell.Windows
If TypeName(ObjWindow.Document) = "HTMLDocument" Then
 WinExist = True
 Set ObjIE = ObjWindow
End If
Next
Set ObjShell = Nothing

If Not WinExist = True Then
Set ObjIE = CreateObject("InternetExplorer.Application")
End If

ObjIE.Navigate "http://nantokakantoka.html"
ObjIE.Visible = True


というような感じです。
Wordの場合はわからなくてすみません。
独学なのでもっといい方法があるかもしれないですが。

Internet Explorerで開いているWindowを取得することはできますよ。

そのためには、まず開いているWindowを順番に取得し、それがInternet Explorerならばそれをオブジェクトに代入し、ひとつもIEウィンドウが存在しない場合は新規作成(CreateObject)すればいいのです。
Windowを取得するにはShell.Applicationというのを使います。

Dim ObjIE As Object
Dim ObjShell As Object
Dim ObjWindow As Object
Dim WinExist As Boolean

WinExist = False
Set ObjShell = CreateObject("Shell.Applicatio...続きを読む

QVBAで工場休日を考慮した作業終了日の出し方

VBAで作業終了日を出したいのですがその時工場休日を考慮したいのです。
テーブル1には作業開始日と作業終了日が格納されています。
テーブル2には工場休日日の一覧が格納されています。

例として、
3月1日作業開始→3月10日に作業終了の場合、
その間3月5日が工場休日の場合は→3月11日に作業終了と出したいのです。
ここで終わりではなく、この後
仮にもし3月11日が工場休日だった場合、上記の結果からまた工場休日のテーブルを検索していって、1日伸ばす。・・となりますよね。
この結果をまた工場休日のテーブルと照らし合わせて最終日が休みではないか確認し、休みだったらまた1日延びる・・となってしまうのですが、
他にアイデアはないでしょうか。またサンプルなどご存知であればアドバイス頂けると助かります。宜しくお願いします。

Aベストアンサー

作業開始日から作業終了日までに含まれる工場休日日の数を数える。
作業終了日を新たな作業開始日とし、作業終了日に工場休日日を足した日を新たな作業終了日とする。
含まれる工場休日日が0日となったら終了。

という感じの再帰関数を作るのはどうでしょうか?
(VBって再帰呼び出しできるの???)

QExcel VBA グラフオブジェクトの使用方法について

Excel2003のVBAについて教えて下さい。
以下の(1)~(4)のコードを用いて セル"A1"に設定された値をグラフスケール(最大値)に設定しようとしています。

(1) scaleData = Worksheets("シート1").Range("A1").Value
(2) Set chartObj = ActiveSheet.ChartObjects(1)
(3) Set chart1 = chartObj.Chart
(4) chart1.Axes(xlValue).MaximumScale = scaleData

グラフオブジェクト単体(グループ化しない)時は問題なく、グラフスケールの設定が行えたのですが、グラフオブジェクトやラベル、ボタンなどを結合すると、(3)で、以下のエラーメッセージが出て、グラフスケールの設定が行えません。

「WorksheetクラスのChartObjectsプロパティを取得できません。」

グループ化することにより、グラフオブジェクトの指定方法が異なるのでしょうか?
解決方法をご存知の方、教えて下さい。宜しくお願い致します。

Excel2003のVBAについて教えて下さい。
以下の(1)~(4)のコードを用いて セル"A1"に設定された値をグラフスケール(最大値)に設定しようとしています。

(1) scaleData = Worksheets("シート1").Range("A1").Value
(2) Set chartObj = ActiveSheet.ChartObjects(1)
(3) Set chart1 = chartObj.Chart
(4) chart1.Axes(xlValue).MaximumScale = scaleData

グラフオブジェクト単体(グループ化しない)時は問題なく、グラフスケールの設定が行えたのですが、グラフオブジェクトやラベル、ボタンなどを結合...続きを読む

Aベストアンサー

#1さんと、表現が異なりますが、同じ事ですね。おまけ付きです。XL2000用です。
'シートモジュールの場合
Sub test()
Me.Shapes("Group 4").GroupItems("Chart 1").DrawingObject.Chart.Axes(xlValue).MaximumScale = 2
End Sub

'おまけ グループ化された図形も含め、図形の名前リストアップ
Sub test2()
Dim shp As Shape
For Each shp In Me.Shapes
Debug.Print Me.Name & ":" & shp.Name
If shp.Type = msoGroup Then Call test3(shp)
Next shp
End Sub

Sub test3(shp As Shape)
Dim shp2 As Shape
For Each shp2 In shp.GroupItems
Debug.Print shp.Name & ":" & shp2.Name
If shp2.Type = msoGroup Then Call test3(shp2)
Next shp2
End Sub

#1さんと、表現が異なりますが、同じ事ですね。おまけ付きです。XL2000用です。
'シートモジュールの場合
Sub test()
Me.Shapes("Group 4").GroupItems("Chart 1").DrawingObject.Chart.Axes(xlValue).MaximumScale = 2
End Sub

'おまけ グループ化された図形も含め、図形の名前リストアップ
Sub test2()
Dim shp As Shape
For Each shp In Me.Shapes
Debug.Print Me.Name & ":" & shp.Name
If shp.Type = msoGroup Then Call test3(shp)
Next shp
End Sub

Sub test3(shp As Shape)
Dim shp2...続きを読む

QExcel VBA 別の二つのbookのシートを、作業bookにコピーする

D:\データ1.xlsx (sheetは一つのみ。シート名:日販)
D:\データX.csv (sheetは一つのみ。シート名:POS積算)

がありまして、エクセルのテンプレート(集計用テンプレート.xlsx)を開いて作業するとします。
テンプレートのbookのシート2にデータ1
          シート3にデータX
のデータを丸々コピーしたいです。シート名もそのままコピーします。
初心者の初心者で、さっぱりできません。。
シート2、シート3のデータを参照するセクションはなんとか出来たので、コピーする記述を教えていただけませんでしょうか。。。

Sub books_open()
Dim bookB As Worksheet, bookC As Worksheet

'対象ブックを開く
Set bookB = Workbooks.Open(ThisWorkbook.Path & "d:\データ1.xls")
Set bookC = Workbooks.Open(ThisWorkbook.Path & "d:\データX.csv")

'対象シートをa.xlsにコピー
bookB.Sheets("sheet1").Copy After:=ThisWorkbook.Sheets(2)
bookC.Sheets("sheet1").Copy After:=ThisWorkbook.Sheets(3)

'シート名変更
With ThisWorkbook
.Sheets(2).Name = "日販"
.Sheets(3).Name = "POS積算"
End With

'対象ブックを閉じる
bookB.Close
bookC.Close
End Sub

コピーが終わったら、作業用テンプレのシート1の5行目に、各列にフィルターを付けるところまでしたいと考えています。。

環境;Windows7 64bit  office2010または2013

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

D:\データ1.xlsx (sheetは一つのみ。シート名:日販)
D:\データX.csv (sheetは一つのみ。シート名:POS積算)

がありまして、エクセルのテンプレート(集計用テンプレート.xlsx)を開いて作業するとします。
テンプレートのbookのシート2にデータ1
          シート3にデータX
のデータを丸々コピーしたいです。シート名もそのままコピーします。
初心者の初心者で、さっぱりできません。。
シート2、シート3のデータを参照するセクションはなんとか出来たので、コピーする記述を教えてい...続きを読む

Aベストアンサー

勘違いが、3点あるように思われます。
まず、1点目ですが、WorkBookとWorkSheetの区別を理解していますか?
今回、BookAが追加になってようですが、これはWorkBookですよね?それに対して、BookBはWorkSheetです。同じような名前を付けてしまったので、分かりずらくなっていると思われます。

2点目です。テンプレートを開いた場合、そのブック名はテンプレートと同じ名前にはなりません。たぶん、後ろに数字が付きます。よって、Workbooks("テスト.xltx")のようにテンプレート名で操作しようとしても「見つからない」みたいなエラーになると思います。

上記のことを踏まえ、今からでも直せるのであれば、次のようにしてみたらいかがでしょうか。

Dim wbA As Workbook, wsB As Worksheet, wsC As Worksheet
'対象ブックを開く
Set wbA = Workbooks.Open("D:\テスト.xltx")
Set wsB = Workbooks.Open("D:\データA.xlsx").ActiveSheet
Set wsC = Workbooks.Open("D:\データX.csv").ActiveSheet
'対象シートをテスト.xltxにコピーしシート名を変更する
wsB.Copy After:=wbA.Sheets(1)

3点目ですが、WorkSheet.CopyメソッドのAfterパラメータの意味を勘違いされているようです。
bookB.Copy After:=ThisWorkbook.Sheets(1) と書いた場合、Sheets(1)の後ろにコピーされます。Sheets(1)自体が書き換わるわけではありません。
ちなみに、bookB.Copy After:=ThisWorkbook.Sheets(2)と書いた場合、Sheets(2)の後ろにコピーされます。当然ですが、Sheets(2)がない場合は、エラーとなります。

上記のことを念頭に、プログラムコードを見直してみてください。ご検討をお祈りします。

勘違いが、3点あるように思われます。
まず、1点目ですが、WorkBookとWorkSheetの区別を理解していますか?
今回、BookAが追加になってようですが、これはWorkBookですよね?それに対して、BookBはWorkSheetです。同じような名前を付けてしまったので、分かりずらくなっていると思われます。

2点目です。テンプレートを開いた場合、そのブック名はテンプレートと同じ名前にはなりません。たぶん、後ろに数字が付きます。よって、Workbooks("テスト.xltx")のようにテンプレート名で操作しようとしても「見つから...続きを読む

QVBAのオブジェクトの値を保持しておくには

ExcelのVBAにおいて、Deleteメソッドを使用して、
オブジェクトを削除する場合に、削除前に保持データを丸々待避させる
よい方法はないでしょうか。

例)グラフタイトルのフォントスタイルを書き戻す。
1. ActiveChart.ChartTitle.Fontの内容を待避させる。
2. Deleteでタイトルを消す。
ActiveChart.ChartTitle.Delete
3. 間に種々処理を行う。
4. 新しいタイトルをつける。
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Characters.Text = "foo"
5. ActiveChart.ChartTitle.Fontの内容を新しいタイトルに適用する。
プロパティーを列挙して変数に格納する方法を試したましたが、
プロパティーの数だけコードを書かなければならないので断念しました。

通常の変数であれば、
1. 規定値をセット(A=1)
2. 退避用の変数にAを保持させる(B=A)
3. Aに対して操作を行う
4. 待避した値をAに書き戻す(A=B)
というようなことができるのですが。
オブジェクトにSet等を試しましたが、Setを使ってオブジェクトを入力した場合、
もとオブジェクトの変化に対して動的に値が変化するため、待避できませんでした。

どなたか、わかる方がいらっしゃいましたら、よろしくお願いいたします。

使用環境
WindowsXP SP2
Excel 2002 SP3

ExcelのVBAにおいて、Deleteメソッドを使用して、
オブジェクトを削除する場合に、削除前に保持データを丸々待避させる
よい方法はないでしょうか。

例)グラフタイトルのフォントスタイルを書き戻す。
1. ActiveChart.ChartTitle.Fontの内容を待避させる。
2. Deleteでタイトルを消す。
ActiveChart.ChartTitle.Delete
3. 間に種々処理を行う。
4. 新しいタイトルをつける。
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Characters.Text = "foo"
5. ActiveChart.ChartTitle.Fon...続きを読む

Aベストアンサー

>Setを使ってオブジェクトを入力した場合、もとオブジェクトの変化に対して動的に値が変化

 そうなんですよね~。オブジェクトの代入は、オブジェクト・アドレスの参照渡しになって、値コピーを行ってくれません。これがVB.NETであれば、CopyやCloneメソッドがあるので、値コピーを行えますが、VBAはVB6仕様なので、恐らくCopyやCloneメソッドの類はありません。
(でも調べて下さいね。そして見つかったら、教えて下さい^^)

>プロパティーを列挙して変数に格納する方法を試したましたが、プロパティーの数だけコードを書かなければならないので断念しました

 私は今まで、これでやって来ました。ただしプロパティーCopy用のClassをつくり、一回作れば、目的のObjectを与えるだけで、Copyから再Copyまで全てやってくれるようにしています。またCopyするプロパティーは必要最小限に抑えています。Classであれば、拡張も容易ですし、ExcelのClassを部品として再利用できます。
 注意点としては、Excel Objectのプロパティーには、それ自体Objectであるものも多数含まれるので、Copyを行う際には、Objectの最下層プロパティーまで遡って、値型(StringやInteger,Singleなど)のプロパティーを退避させる必要のある事です。

>Setを使ってオブジェクトを入力した場合、もとオブジェクトの変化に対して動的に値が変化

 そうなんですよね~。オブジェクトの代入は、オブジェクト・アドレスの参照渡しになって、値コピーを行ってくれません。これがVB.NETであれば、CopyやCloneメソッドがあるので、値コピーを行えますが、VBAはVB6仕様なので、恐らくCopyやCloneメソッドの類はありません。
(でも調べて下さいね。そして見つかったら、教えて下さい^^)

>プロパティーを列挙して変数に格納する方法を試したましたが、プロパティー...続きを読む

QVBAでのセルの選択で Cells Range R1C1 の使い分け

セルを指定するときに
Cells Range R1C1のどれかを使うと思いますが、
どういうときにどれを使うといった決まりはあるのでしょうか?

慣れとか好みで使い分けるのでしょうか?

ひとつのプロジェクトに対して、
CellsならCellsで一貫して使ったほうがわかりやすいと思うのですが
そういう理解でいいのでしょうか?

VBAの勉強をはじめたばかりなので、
おかしな質問だったら失礼します。

Aベストアンサー

こんばんは。

Excel VBA の Cells や Range などの使い分けですが、
(1) Cells
 1つのセル位置に対して操作する場合に使用します。
 また、for 文などで、列方向や行方向に移動しながら
 繰り返し処理する場合に、セル位置をループの
 カウンタ変数を使って指定できます。

 for rowNo = 1 to 3
  for colNo = 1 to 2
   msgbox "行 : " & rowNo & ", 列 : " & colNo & _
     ", 値 : " & Cells( rowNo, colNo ).value
  next
 next

(2) Range
 セル位置が固定で指定する場合やセル範囲を指定する
 場合、あるいは Range でしか使用できないメソッド
 やプロパティを使用する場合に使用します。

 Range("A1").Select
 Range("A1:B3").ClearContents
 Range( Cells(1,1), Cells(2,3) ).Select

こんばんは。

Excel VBA の Cells や Range などの使い分けですが、
(1) Cells
 1つのセル位置に対して操作する場合に使用します。
 また、for 文などで、列方向や行方向に移動しながら
 繰り返し処理する場合に、セル位置をループの
 カウンタ変数を使って指定できます。

 for rowNo = 1 to 3
  for colNo = 1 to 2
   msgbox "行 : " & rowNo & ", 列 : " & colNo & _
     ", 値 : " & Cells( rowNo, colNo ).value
  next
 next

(2) Range
 セル位置が固定で指定する...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング