tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル[Excel]行をコピーして挿入
記事No1295
投稿日: 2005/01/19(Wed) 16:51
投稿者ひろぼ
[OSのVer]:WindowsXP    [VBのVer]:VB.NET 
はじめまして。
既存のEXCELシートにデータを出力する処理を書いています。
EXCELのプロセスが残ってしまう問題をこちらのサンプルを参考にして処理しました。
しかし、データ数が1ページより多い場合に「必要ページ分の行をコピーして挿入する」ようにしてい
ます。
この処理を行った場合、プロセスが残ってしまいます。
xlsRangeの設定の仕方が間違っているような気がするのですが、わかりません。
ご教授ください。

'必要ページ分の行をコピーして挿入する関数
Private Sub pCopyPaste(ByVal xlsSheet As Excel.Worksheet, _
            ByRef iStart As Integer, _        'コピー元の開始行
            ByRef iEnd As Integer, _        'コピー元の終了行
            ByVal i1PageCnt As Integer, _        '1ページ分の行数
            ByVal iCount As Integer)        '何ページ分コピーしたいか

Dim xlsCells As Excel.Range
    xlsCells = xlsSheet.Cells
    Dim xlsRange As Excel.Range = xlsSheet.Rows
    xlsRange(iStart & ":" & iEnd).Copy()
    xlsRange(iEnd + 1 & ":" & iEnd + i1PageCnt * iCount).Select()
    xlsRange(iEnd + 1 & ":" & iEnd + i1PageCnt * iCount).PasteSpecial
(Excel.XlPasteType.xlPasteAll)
    '改ページを設定しなおす処理
    xlsCells.PageBreak = Excel.XlPageBreak.xlPageBreakNone
    xlsRange(iEnd + 1).PageBreak = Excel.XlPageBreak.xlPageBreakManual
    xlsRange(iEnd / 2 + 1).PageBreak = Excel.XlPageBreak.xlPageBreakManual
    For intLoop = 1 To iCount
        xlsRange((iEnd + i1PageCnt * intLoop) + 1).PageBreak =
Excel.XlPageBreak.xlPageBreakManual
        xlsRange((iEnd + i1PageCnt * intLoop) / 2 + 1).PageBreak =
Excel.XlPageBreak.xlPageBreakManual
    Next
    xlsSheet.Select()
    MRComObject(xlsCells)            'xlsRange の開放
    MRComObject(xlsRange)            'xlsSheet の開放
End Sub

[ツリー表示へ]
タイトルRe: [Excel]行をコピーして挿入
記事No1297
投稿日: 2005/01/19(Wed) 18:32
投稿者花ちゃん
自分で書いたコードの間違いは自分で探すようにして下さい。
(人に頼むなら事象を再現できるコードを投稿するようにして下さい。
ひょっとすれば、投稿されたコード以外の部分に原因があるかも知れないし、
ここが間違っていますよと、指摘しても、すみません。投稿する時に間違ったコードを
投稿してしまいました。という人が今までにも何人もありましたし、すみません、説明
不足で、や再質問を投げかけてもそれに対する返信がなかなか返ってこなかったり・・・・)
私も多分あそこだろうとは解るのですが、プログラムを実行して確認しない事には答え
にくいです。

>xlsRangeの設定の仕方が間違っているような気がするのですが
なら、リンクを貼っていた先に魔界の仮面弁士さんのサンプルや解説があるのでよく見て
下さい。
又、私のサンプルのVB.NETからExcel にデータを送りグラフを表示するでのRange の使い方
そのような使い方をしていなかったかと思います。

本来はコードを書く時に正常に終了しているか確認しながらコードを追加するべきかと
思います。(私のような未熟者はそのようにしながら進めています。)

後から調べるなら、問題がありそうな部分をコメント化して見てどうなるか確認して
みれば解るかと思うのですが。

まずは、関数の部分を全てコメントアウトして実行して正常に終了しているか確認して
下さい。
それで正常に終了していれば、関数内で間違っている可能性があるので順次コメントを
外しながら確認していけば不具合箇所が見つかるはずです。

その部分の修正方法が解らなければ、それはそれで質問されたらいいかと思いますが、
自分でやるべき事(やれる事)は、自分でやって下さい。

又、掲示板のログ等を検索して調べれば、色々あるかと、下記のような方法もあります。
hhttp://www.bcap.co.jp/hanafusa/bbs/wforum.cgi?no=1260&reno=no&oya=1260&mode=msgview&page=0

PS:コードを投稿するときは、図表モードで投稿してください。
  修正からでも、修正できますので修正しておいて下さい。

[ツリー表示へ]
タイトルRe^2: [Excel]行をコピーして挿入
記事No1300
投稿日: 2005/01/20(Thu) 10:36
投稿者ひろぼ
質問の仕方、書き方に問題がありました。すみませんでした。
また、自分がずいぶん知識がなかったことがわかりました。
コードの抜粋の仕方に問題がありますね。
とにかく、前回の発言を修正しなければなりませんが、少々お待ちください。

[ツリー表示へ]
タイトル解決しました。申し訳ありませんでした
記事No1303
投稿日: 2005/01/20(Thu) 11:41
投稿者ひろぼ
[OSのVer]:Windows    [VBのVer]:VB.NET  
自己解決しました。本当にその都度、解放しなければならないのですね。
大変申し訳ありませんでした。
一応、コードをのせておきます。大変失礼いたしました。

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click

        Dim iSheetsCount As Integer
        Dim sSheetName() As String
        Dim intLoop As Integer
        Dim iRow As Integer
        Dim sFileName As String = "C:\Test.xls"     'シート数3
        '================== 起動時の処理 =================== 
        Dim xlsApp As New Excel.Application
        Dim xlsBooks As Excel.Workbooks = xlsApp.Workbooks
        '既存のファイルを開く場合
        Dim xlsBook As Excel.Workbook = xlsBooks.Open(sFileName)
        Dim xlsSheets As Excel.Sheets = xlsBook.Worksheets
        Dim xlsSheet As Excel.Worksheet
        Dim xlsCells As Excel.Range
        Dim xlsRange As Excel.Range
        xlsApp.DisplayAlerts = False

        '全シート名を取得する
        iSheetsCount = xlsSheets.Count
        ReDim sSheetName(iSheetsCount)
        For intLoop = 1 To iSheetsCount
            xlsSheet = xlsSheets(intLoop)
            sSheetName(intLoop) = xlsSheet.Name
            MRComObject(xlsSheet)            'xlSheet の開放
        Next
        '1シート目を取得
        xlsSheet = xlsSheets(1)
        'データを入れる
        For iRow = 1 To 30
            xlsCells = xlsSheet.Cells
            xlsRange = xlsCells(iRow, 1)
            xlsRange.Value = CStr(iRow)
            MRComObject(xlsCells)            'xlRange の開放
            MRComObject(xlsRange)            'xlSheet の開放
        Next
        '1ページ目(30行)をコピーして3ページ分にする
        pCopyPaste(xlsSheet, 1, 30, 30, 2)
        MRComObject(xlsSheet)            'xlSheet の開放

        '2ページ目を削除する
        xlsSheet = xlsSheets(2)
        xlsSheet.Delete()
        MRComObject(xlsSheet)            'xlSheet の開放

        xlsSheets.Select()
        'ファイルを保存する
        xlsBook.SaveAs("C:\Test2.xls")
        Erase sSheetName
        xlsApp.DisplayAlerts = True
        '================== 終了時の処理 =================== 
        MRComObject(xlsSheets)           'xlSheets の開放
        xlsBook.Close()             'xlBook を閉じる
        MRComObject(xlsBook)             'xlBook の開放
        MRComObject(xlsBooks)            'xlBooks の開放
        xlsApp.Quit()                    'Excelを閉じる    
        MRComObject(xlsApp)              'xlApp を開放

    End Sub


    Private Sub pCopyPaste(ByVal xlsSheet As Excel.Worksheet, _
                    ByRef iStart As Integer, ByRef iEnd As Integer, ByVal i1PageCnt As
Integer, ByVal iCount As Integer)

        Dim intLoop As Integer
        Dim xlsCells As Excel.Range
        Dim xlsRows As Excel.Range
        Dim xlsRange As Excel.Range

        xlsRows = xlsSheet.Rows
        xlsRange = xlsRows(iStart & ":" & iEnd)
        xlsRange.Copy()
        MRComObject(xlsRange) 'xlsRange の開放
        xlsRange = xlsRows(iEnd + 1 & ":" & iEnd + i1PageCnt * iCount)
        xlsRange.Select()
        xlsRange.PasteSpecial(Excel.XlPasteType.xlPasteAll)
        xlsSheet.Select()
        MRComObject(xlsRange) 'xlsRange の開放
        MRComObject(xlsRows) 'xlsRows の開放

        '改ページを設定しなおす処理
        xlsCells = xlsSheet.Cells
        xlsCells.PageBreak = Excel.XlPageBreak.xlPageBreakNone
        MRComObject(xlsCells) 'xlsCells の開放
        xlsRows = xlsSheet.Rows
        For intLoop = 0 To iCount
            xlsRange = xlsRows((iEnd + i1PageCnt * intLoop) + 1)
            xlsRange.PageBreak = Excel.XlPageBreak.xlPageBreakManual
            MRComObject(xlsRange) 'xlsRange の開放
        Next
        MRComObject(xlsRows) 'xlsRows の開放

    End Sub

    Private Sub MRComObject(ByVal objXl As Object)
        'Excel 終了処理時のプロシージャ
        Try
            '提供されたランタイム呼び出し可能ラッパーの参照カウントをデクリメントします
            System.Runtime.InteropServices.Marshal.ReleaseComObject(objXl)
        Catch
        Finally
            objXl = Nothing
        End Try
    End Sub

[ツリー表示へ]