[リストへもどる]
一括表示

投稿時間:2004/08/10(Tue) 12:06
投稿者名:uchi
URL :
タイトル:
エクセルシートの1行ずつを別ブックにコピー
お世話になります。

エクセルVBAでの開発はありますが、VBでのオブジェクト操作は初めてです。
こちらのサイトのサンプルを参考にして、既存エクセルシートの内容を1行ずつ、
新規ブックのシートにコピーするプログラムを作成しました。
(シートコピーの方が早いですが、ここでは1行ずつのコピーとしています。)

[以下のプログラムをご参照下さい]
(1)実行結果は、DisplayAlert=Falseを入れているのにも関わらず、自動的に作成されたブックの
  保存を確認するメッセージが表示されてしまいます。
  また、作成された「結果.xls」をダブルクリックして開くと、コピー元シートの行数分の
  エクセルファイルが作成されていて、それらも開いてしまいます。
(2)オブジェクト操作が初めてのため、For-Nextの中での文法エラー、
  かつ、処理終了後にエクセルタスクを残さないように、試行錯誤して行き着いたのが
  今のロジックです。
  しかし、結果.xlsにデータがコピーされていないので、ロジックエラーがあるようです。
  さらに処理時間は、エクセルVBAで実行するのに比べて、かなり遅いです。

上記(1)(2)の点について、下記のロジックでの不具合をご指摘ください。
お手数ですが、よろしくお願いします。

-----------------------------------------------------------------------------
Private Sub Command1_Click()
    'xlBook2の内容を1行ずつxlBook1にコピーする練習
    'テスト環境:Win2000(SP4) VB6(SP6) EXCEL2000

    Dim xlApp As Excel.Application
    Dim xlBook1 As Excel.Workbook, xlBook2 As Excel.Workbook
    Dim xlSheet1 As Excel.Worksheet, xlSheet2 As Excel.Worksheet
    
    Dim RowPos As Long    'xlBook2のxlSheet2シートの最大行を保存
    Dim i As Long      'For-Nextのカウンター
    
    Set xlApp = CreateObject("Excel.Application")
    '新規のブック
    Set xlBook1 = xlApp.Workbooks.Add
    Set xlSheet1 = xlBook1.Worksheets(1)
    '既存のブック(ReadOnlyで開く)
    Set xlBook2 = xlApp.Workbooks.Open("C:\データ.xls",,True)
    Set xlSheet2 = xlBook2.Worksheets("sheet1")
    
    xlApp.Visible = False            
    xlApp.Application.ScreenUpdating = False  'xlApp.ScreenUpdating = True?
    
    'xlBook2のsheet1シートの使用されている最大行を取得(A列のセルは必ずセットされている)
    RowPos = xlSheet2.Range("A65536").End(xlUp).Row  
    
    '1行ずつをコピー
    For i = 1 To RowPos
   xlApp.Application.CutCopyMode = False
   xlBook2.Activate
   xlSheet2.Activate
   xlSheet2.Rows(i & ":" & i).Select
   xlApp.Selection.Copy
   xlBook1.Activate
   xlSheet1.Activate
   xlSheet1.Range("A" & i).Select
   xlApp.ActiveSheet.Copy
    Next i
    
    'ファイルの保存と終了
    xlApp.Application.DisplayAlerts = False
    xlSheet1.SaveAs ("C:\結果.XLS")    'xlBook1.SaveAS("...") ?
    xlBook2.Close (False)
    xlApp.Application.DisplayAlerts = True

    xlApp.Application.ScreenUpdating = True   'xlApp.ScreenUpdating = true ?
    xlApp.Application.Quit       'xlApp.Quit ?
    
    Set xlSheet1 = Nothing
    Set xlSheet2 = Nothing
    Set xlBook1 = Nothing
    Set xlBook2 = Nothing
    Set xlApp = Nothing
    
End Sub
-----------------------------------------------------------------------------

投稿時間:2004/08/10(Tue) 22:54
投稿者名:Renard
Eメール:
URL :
タイトル:
Re: エクセルシートの1行ずつを別ブックにコピー
質問がよく分からないのですが、とりあえずソースの赤入れ。

> -----------------------------------------------------------------------------
> Private Sub Command1_Click()
>     'xlBook2の内容を1行ずつxlBook1にコピーする練習
>     'テスト環境:Win2000(SP4) VB6(SP6) EXCEL2000
>
>     Dim xlApp As Excel.Application
>     Dim xlBook1 As Excel.Workbook, xlBook2 As Excel.Workbook
>     Dim xlSheet1 As Excel.Worksheet, xlSheet2 As Excel.Worksheet
>    
>     Dim RowPos As Long    'xlBook2のxlSheet2シートの最大行を保存
>     Dim i As Long      'For-Nextのカウンター
>    
>     Set xlApp = CreateObject("Excel.Application")
>     '新規のブック
>     Set xlBook1 = xlApp.Workbooks.Add
>     Set xlSheet1 = xlBook1.Worksheets(1)
>     '既存のブック(ReadOnlyで開く)
>     Set xlBook2 = xlApp.Workbooks.Open("C:\データ.xls",,True)
      Set xlBook2 = xlApp.Workbooks.Open("C:\データ.xls",ReadOnly:=True) とした方が分かりやすい

>     Set xlSheet2 = xlBook2.Worksheets("sheet1")
>    
>     xlApp.Visible = False            
>     xlApp.Application.ScreenUpdating = False  'xlApp.ScreenUpdating = True?
      xlApp.ScreenUpdating = False     '非表示なのに必要なのかな?(未検証)

>     'xlBook2のsheet1シートの使用されている最大行を取得(A列のセルは必ずセットされている)
>     RowPos = xlSheet2.Range("A65536").End(xlUp).Row  
>    
>     '1行ずつをコピー
>     For i = 1 To RowPos
>    xlApp.Application.CutCopyMode = False
>    xlBook2.Activate
>    xlSheet2.Activate
>    xlSheet2.Rows(i & ":" & i).Select
>    xlApp.Selection.Copy
>    xlBook1.Activate
>    xlSheet1.Activate
>    xlSheet1.Range("A" & i).Select
>    xlApp.ActiveSheet.Copy
>     Next i
'コピーする時は、範囲を直接指定します。Activeにする必要なし。
'selectionとかも、普通使わない。
    For i = 1 To RowPos
        xlSheet2.Range("a" & CStr(i) & ":" & "iv" & CStr(i)).Copy _
            xlSheet1.Range("a" & CStr(i))
    Next i
    
>     'ファイルの保存と終了
>     xlApp.Application.DisplayAlerts = False
      xlApp.DisplayAlerts = False

>     xlSheet1.SaveAs ("C:\結果.XLS")    'xlBook1.SaveAS("...") ?
      xlBook1.SaveAs "C:\結果.xls"
      xlBook1.Close                         '閉じるのを忘れずに

>     xlBook2.Close (False)
      'Methodの引数には普通括弧をつけない

>     xlApp.Application.DisplayAlerts = True
>
>     xlApp.Application.ScreenUpdating = True   'xlApp.ScreenUpdating = true ?
>     xlApp.Application.Quit       'xlApp.Quit ?
      'ここら辺もね。xlAppがApplicationなんだから・・・。

>     Set xlSheet1 = Nothing
>     Set xlSheet2 = Nothing
>     Set xlBook1 = Nothing
>     Set xlBook2 = Nothing
>     Set xlApp = Nothing
>    
> End Sub
> -----------------------------------------------------------------------------

投稿時間:2004/08/11(Wed) 08:34
投稿者名:uchi
URL :
タイトル:
Re^2: エクセルシートの1行ずつを別ブックにコピー
Renardさま、ありがとうございます。

赤入れしていただいたソースに修正して、実行させたところ、
問題点だった
(1)コピー元シートの行数分のファイルが作成される。しかも、中身は空。
(2)for-nextの中のロジックが不格好で、ブックやシートのActivateを繰り返しているためか、
  非常に処理時間がかかる。
は、解決しました。
エクセルの自動マクロ作成機能で作られたソースに、xlApp,xlBook1,xlSheet1を付けただけだと、
正常に機能しないのですね。

また、細かい指摘事項も初心者の私にとって勉強になりました。
ありがとうございました。