「夫を成功」へ導く妻の秘訣 座談会

はじめまして。
色々検索してみたのですが、なかなか見つからなかったのでお力を貸していただければと思います。

仕事でVB6.0でつくられたプログラムがあります。
最初は別の方(仮にAさんとします)が作ってくださり、いつもそのexeファイルをもらって仕事をしておりました。
この度、私がそのプログラムを修正し、exeファイルを作成したところ、自分のPCでは問題なく動くのですが、他のPCで使用しようとするとエラーが発生して動きません。

プログラムはVB6.0で、指定したエクセルファイルを開いて参照し、データと照合させるものです。

AさんのPCのOSはwinXPです。
Aさんが作ってくれたexeファイルはコピーして、Win95/Win98/WinXPで問題なく動作することが出来ました。
しかし私が修正し、作成したexeファイルはOSは関係なく自分のPC以外ではエラーが発生してしまいます。ちなみに自分のPCもWinXPです。
エラーは「不正な処理をしている為、このプログラムを終了します」という様なものです。
エクセルを参照しようとすると、発生するエラーなので、そのときだとは思うのですが、デバックしようにも、自分のPCでは問題なく動いてしまうので、どうにも出来ません。

よろしくお願い申し上げます。

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

A 回答 (6件)

原因は 事前(アーリー)バインディングつまり参照設定をしているためです


yuzumiya氏のパソコンにはExcel2003、ターゲットパソコンにはExcel2000 ということですね

VBのアプリはExcel2003を探しているが見つからないので落ちてしまうのです

As Objectになおして EXcel2003への参照設定も外して EXEを作成してください

この回答への補足

回答有難うございます。

>原因は 事前(アーリー)バインディングつまり参照設定をしているためです
>VBのアプリはExcel2003を探しているが見つからないので落ちてしまうのです
⇒なるほど!VBでExcel2003を探しているため、エラーが発生していたのですね!!

>As Objectになおして EXcel2003への参照設定も外して EXEを作成してください
⇒修正するものは、以下の2点で宜しいでしょうか?
(1)参照設定の「Microsoft Excel 11.0 Object Library」のチェックを外す。
(2)プログラム内の全ての箇所で以下の修正を行う。(関数の引数も含めて)
As excel.Application ⇒ As Object
As excel.Workbook   ⇒ As Object
As excel.Worksheet  ⇒ As Object

これから、修正してみます。

補足日時:2008/05/08 17:09
    • good
    • 0
この回答へのお礼

何度も何度も、回答していただき、本当に有難うございました。

参照設定の「Microsoft Excel 11.0 Object Library」のチェックは外さずに、プログラム内の全ての箇所で(関数の引数も含めて)
以下の修正を行ったところ、他のPCでもエラーが発生することなくきちんとアプリが動作することが出来ました。
 As excel.Application ⇒ As Object
 As excel.Workbook   ⇒ As Object
 As excel.Worksheet  ⇒ As Object

本当に、ありがとうございました。

お礼日時:2008/05/08 18:57

元の質問の『不正な処理をしている為、このプログラムを終了します』のメッセージは作成したアプリで生成しているメッセージなのでしょうか、それとも Windowsが生成した物ですか?



また補足などに投稿されたコードのどの部分をどのように変更なさったのでしょう
excelfile_openプロシージャは機能しているのでしょうか

もしかして あなたのパソコンにインストールされているExcelは複数ではありませんか
その中の最新版のExcelと他のパソコンのExcelでバージョンが違うのでありませんか

Dim xlApp As excel.Application
といった具合で 事前(アーリー)バインディングするなら使用環境も同じExcelのバージョンである必要があります

違うバージョンが存在するなら
excelfile_openの中でやっているように Excel関連のオブジェクトを
As Objectで宣言して使いましょう

開発時は アーリーバインディングデングでインテリセンスを使いながら開発したほうが効率的でしょう
リリース時点で As Objectに置き換え
Excel.Applicationを新規に起こす場合は CreateObjectまたはGetObjectを使いましょう

この回答への補足

返信が遅くなって申し訳ございません。
会社がお休みになってしまい、自宅からはアクセス出来ない為、こんなに遅れてしまい申し訳ありません。

>元の質問の『不正な処理をしている為、このプログラムを終了します』のメッセージは作成したアプリで生成しているメッセージなのでしょうか、それとも Windowsが生成した物ですか?
⇒Windowsが生成したものです。

>また補足などに投稿されたコードのどの部分をどのように変更なさったのでしょう
⇒投稿した箇所は一切修正を行っておりません。以前のままです。
>excelfile_openプロシージャは機能しているのでしょうか
⇒こちらも一切修正しておりませんし、自分のPCでは動いているので、機能していると思います。
>もしかして あなたのパソコンにインストールされているExcelは複数ではありませんか
⇒私のPCにはOffice2003しかインストールされておりません。
>その中の最新版のExcelと他のパソコンのExcelでバージョンが違うのでありませんか
⇒他のPCはOffice2000が殆どです。それよりバージョンの低いもののあります。ちなみに、以前作成していた方のPCはおそらくOffice2000と思われます。(本人がいないので確認は取れてはおりませんが)

>Dim xlApp As excel.Application
>といった具合で 事前(アーリー)バインディングするなら使用環境も同じExcelのバージョンである必要があります
>違うバージョンが存在するならexcelfile_openの中でやっているように Excel関連のオブジェクトをAs Objectで宣言して使いましょう
⇒「excelfile_openの中でやっているように」というのは、どのコードの事を仰っているのでしょうか?

補足になるか分かりませんが、VBの[プロジェクト]-[参照設定]の「Microsoft Excel 11.0 Object Library」というものにチェックが入っております。

補足日時:2008/05/07 11:25
    • good
    • 0
この回答へのお礼

回答有難うございます。
助言頂いた箇所を、以下のように修正を行いましたが、やはり同じエラーが発生してしまいました。
--------------------------------
Private Sub Combo2_Click()

Dim i As Integer
Dim xlApp As Object  ← 修正後
Dim xlBook As Object  ← 修正後
Dim xlSheet As Object ← 修正後
' Dim xlApp As excel.Application ← 修正前
' Dim xlBook As excel.Workbook  ← 修正前
' Dim xlSheet As excel.Worksheet ← 修正前
Dim fa As String, excelfile_path As String, terminal As String
Dim Msg As String, Style As Integer, Title As String
Dim terminal_Column As Integer, path_Column As Integer, path_name As String, Del_Line As Boolean

'エクセルのファイルパス名
fa = App.Path
If Right(fa, 1) <> "\" Then fa = fa & "\"
excelfile_path = fa & Text8.Text & Label7

'比較EXCELファイルの存在確認
If comp_excelfile_check(excelfile_path) = False Then Exit Sub

Combo3.Enabled = False

Combo3.Clear
Combo3.Text = "(商品を選択してください)"

Call excelfile_open(xlApp, xlBook, xlSheet, excelfile_path, "【参考】シート名")

terminal = Combo2.Text

i = xlSheet.Range("C13:C65536").Find(terminal, , , xlPart, , , , False).Row
Do While xlSheet.Cells(i, 3).Text = terminal
Combo3.AddItem xlSheet.Cells(i, 4).Value
i = i + 1
Loop

Combo3.Enabled = True
Check5.Visible = False
Check5.Value = 2
Check12.Visible = False
Check12.Value = 2


End Sub
--------------------------------
まだ、どこかおかしいのでしょうか?

お礼日時:2008/05/07 11:58

新しいEXEの起動時にそのエラーが発生するのでしょうか


それともあるアクション(イベント)を実行した場合に起きるのでしょうか

エラーになっているであろう部分に MsgBoxなどを埋め込んで
何処まで期待通りに実行されているのか確認しましょう

今回の修正は何をしたのでしょうか

具体的なコードの提示があったほうが回答がつきやすいですよ

旧OSなどで検証が必要なら 仮想PC系のアプリケーションを導入してみましょう
Virtual PCや VMWareなど …

この回答への補足

回答有難うございます。返信遅れてもうしわけありませんでした。

exeは起動します。
イベント実行時にエラーが発生してしまいます。

exeを起動させると、ファイル名を入れるtextboxやアイテムを入れるcomboboxが表示されます。

イメージとしては、エクセルファイルにA社~D社で扱っている商品が表で纏めてあります。
そして、1つめのcombo.boxをクリックするとA社,B社,C社,D社と選べるようになり、これを選択すると、2つめのcombo.boxに、選んだ会社で扱っている商品が選べるようにcombo.boxのプルダウンに設定されるというものになります。

エラーが発生するのは、このcombo.boxでA社~D社を選択した時です。

エクセルファイルを開くプログラムで何かおかしな事になっている可能性があるのですが、この辺りは全く私は手を出していません。
いじる必要がありませんので、いじっていないのですが・・・。

その辺りのプログラムは以下の通りです。
Private Sub Combo2_Click()

Dim i As Integer
Dim xlApp As excel.Application
Dim xlBook As excel.Workbook
Dim xlSheet As excel.Worksheet
Dim fa As String, excelfile_path As String, terminal As String
Dim Msg As String, Style As Integer, Title As String
Dim terminal_Column As Integer, path_Column As Integer, path_name As String, Del_Line As Boolean

'エクセルのファイルパス名
fa = App.Path
If Right(fa, 1) <> "\" Then fa = fa & "\"
excelfile_path = fa & Text8.Text & Label7

'比較EXCELファイルの存在確認
If comp_excelfile_check(excelfile_path) = False Then Exit Sub

Combo3.Enabled = False
Combo3.Clear
Combo3.Text = "(商品を選択してください)"

Call excelfile_open(xlApp, xlBook, xlSheet, excelfile_path, "【参考】シート名")

'エクセルを表示します。(表示しなくてもOK)
'xlApp.Visible = True

terminal = Combo2.Text

i = xlSheet.Range("C13:C65536").Find(terminal, , , xlPart, , , , False).Row
Do While xlSheet.Cells(i, 3).Text = terminal
Combo3.AddItem xlSheet.Cells(i, 4).Value
i = i + 1
Loop

Combo3.Enabled = True
Check5.Visible = False
Check5.Value = 2
Check12.Visible = False
Check12.Value = 2

End Sub

Function comp_excelfile_check(ByVal excelfile_path As String) As Boolean
'比較EXCELファイルの存在確認

Dim Msg As String, Style As Integer, Title As String
Dim excelfile_name As String

excelfile_name = Mid(excelfile_path, InStrRev(excelfile_path, "\") + 1)

If Dir(excelfile_path, vbNormal) = "" Then
Msg = "比較ファイル『" & excelfile_name & "』が見つかりません。" ' メッセージを定義します。
Style = vbExclamation ' ボタンを定義します。
Title = "注意" ' タイトルを定義します。
MsgBox Msg, Style, Title
comp_excelfile_check = False
Else
comp_excelfile_check = True
End If

End Function

ちなみに、EXCELファイルの存在確認である、comp_excelfile_checkプログラムでは、存在しないファイル名で行うと、きちんと「ファイルが存在しません」とメッセージが出力されるので、ここまでは問題なく動いていることは分かっています。

補足日時:2008/04/30 10:37
    • good
    • 0
この回答へのお礼

ゴメンなさい。もう一つ、エクセルファイルを開くプログラムを記載し忘れてしまいました。
以下になります。
Sub excelfile_open(xlApp As excel.Application, xlBook As excel.Workbook, xlSheet As excel.Worksheet, ByVal excelfile_path As String, ByVal sheet_name As String)
'エクセルファイルの取得

Dim excelfile_name As String

excelfile_name = Mid(excelfile_path, InStrRev(excelfile_path, "\") + 1)

On Error Resume Next
'エクセルを起動して、ファイルを開く
'Set xlApp = CreateObject("Excel.Application")
'Set xlBook = xlApp.Workbooks.Open(ExcelFile_path)
Set xlApp = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Set xlApp = CreateObject("Excel.Application")
Err.Clear
End If
Set xlBook = xlApp.Workbooks(excelfile_name)
If Err.Number <> 0 Then
'保存確認のメッセージを非表示にする。
xlApp.DisplayAlerts = False
Set xlBook = xlApp.Workbooks.Open(excelfile_path)
xlApp.DisplayAlerts = True
End If
Set xlSheet = xlBook.Worksheets(sheet_name)
On Error GoTo 0

'エクセルを表示します。(表示しなくてもOK)
'xlApp.Visible = True

End Sub

よろしくお願い申し上げます。

お礼日時:2008/04/30 11:02

VB6のexeはVB6用のコンポーネントが実行時に必要です。

exeだけコピーして動くのは、コンポーネントがインストール済みだからです。
修正時に新しいコンポーネントを追加しませんでしたか?
いずれにしても、ディストリビューション・ウィザードでインストールキットを作成して頒布するのが正しい方法です。
これを嫌ってWebアプリケーションにしているプロジェクトが増えています。
Webアプリケーションだとクライアント側に何もインストールする必要がないですから。

この回答への補足

回答有難うございます。返信が遅れてしまい申し訳ございません。
> exeだけコピーして動くのは、コンポーネントがインストール済みだからです。
修正時に新しいコンポーネントを追加しませんでしたか?
コンポーネントがインストール済みというのは、どういう意味でしょうか?修正は、エクセルの参照セルを変更する程度のものです。

以前も、exeだけコピーして使えており、特に何かをインストールしてはおりませんでした。

webアプリケーションですか。初めて聞きました。調べてみます。

ご意見ありがとうございました。

補足日時:2008/04/30 10:33
    • good
    • 0

何かのコンポーネントで使うライブラリを「実行時に動的にロードして使用」にしているのかも。



Aさんは、すべてのコンポーネントを「実行ファイルに含める」にしているので、何も入れてない、どのPCでも動く。

質問者さんが書き換えた場所で使うライブラリを「実行時に動的にロードして使用」にしていると「VBのランタイムライブラリをインストール済み」のPCでしか動かなくなる。

「VBの開発環境がインストール済み」であれば「VBのランタイムライブラリもインストール済み」なのは確実。

「VBのランタイムライブラリがインストールされてないPC」で実行すると、ライブラリを使おうとしてもライブラリのロードと初期化に失敗する。

プログラムが「ライブラリのロードと初期化に成功したか?」をチェックせずに、失敗時にも成功したつもりでライブラリの関数を呼び出すと、当然
>エラーは「不正な処理をしている為、このプログラムを終了します」という
結果になるのは明白。

つまり
>自分のPCでは問題なく動くのですが、他のPCで使用しようとするとエラーが発生して動きません。
って状態になる訳。

実行ファイルを作成する際の、ライブラリオプションを良~く確認しましょう。

この回答への補足

早速の回答ありがとうございました。
回答頂いたライプラリオプションの件確認してみたいのですが、私初心者でして、全く分かりません。

大変申し訳ございませんが、どこをどのようにしたら良いでしょうか?

実は、VBの勉強をしたことが全くなく、Aさんから引き継がれたプログラムを必死に眺めてネットで検索して独学したので、知識がほぼ0ナノです。お手数お掛けします・・・。
はじめに、きちんとお知らせしておくべきでしたね。申し訳ありません。

補足日時:2008/04/25 18:01
    • good
    • 0

最下位のOSで動くようにコーディングすることです。


最上位のOSでのみ動くように書いたらダメです。
ですから、Win95で開発してWin98やWinXPで動作確認したが手っ取り早いと思います。

この回答への補足

早速の回答ありがとうございました。
95/98でexeファイルを作成すれば良いという事でしょうか?

最初にプログラムを開発したときのOSが既にXPで、win95/98でも動いていたのですが・・・。

ちなみに、他のXPでも同じエラーが発生してしまうのです。

補足日時:2008/04/25 17:40
    • good
    • 0

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

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

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

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

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

QEXEファイルを実行できません。

VB6でプログラムをつくりました(OS:WINDOWS98)が、EXEファイルを他のPC(OS:WINDOWS2000/WINDOWS95等)で実行させるのですが、うまくうごきません。API関数を使用しているのでこのためかと思いますが、どのように対処したらよいかわかりません。
"SLEEP"
"RegCloseKey/RegOpenKeyEx"
"RegQueryValueExstr"
"Keybd_event"
を使用しています。
他のPCにはソフトの干渉からVBをインストールすることはできません。
DLLをシステムに入れることなら問題ないのですが、どなたか教えていただけませんか?

Aベストアンサー

他のPCには、VB6 の環境が全く入っていないということですよね。
そうであれば、EXE ファイルだけを単体で持っていっても、動きません。ランタイムライブラリが必要です。

ランタイムライブラリは、パッケージになったものがネットからでもDLできると思いますが、それよりも、No.1 の方がおっしゃるように、セットアップパッケージを作成した方がベターです。

セットアップパッケージは、VB6 の「ディストリビューション ウィザード」で簡単に作成できます。
このプログラムを立ち上げて、質問に答えていくだけで、配布用のパッケージを作ることができます。
完成したパッケージには、そのプログラムを動かすのに必要なランタイムライブラリがすべて含まれていますので、全く何もない環境に持っていっても、正しくインストールすることができます。

これを実際にやってみて、わからないことがあれば、補足して下さい。

QVB6のプログラムをWIN7で使いたい

OSをXpからWIN7に移行しなければならなくなり、環境移行のテストをしています。
VB6で組まれた業務用プログラムがあり、現在Xpで動作しています。
このプログラム自体はWIN97の時代に作成されたものです。
簡単に説明しますと、データがAccessのデータベースにあり、それを使って技術計算をするプログラムです。
WIN97に入れると、セットアップは成功するのですが、Accessとデータをやり取りする部分でエラーが起きているようです。
そもそも、VB6自体がWIN7にはセットアップできないようで、再コンパイルできません(再コンパイルで動くかどうかも不明ですが)。
WIN7上で動かす良い方法がないでしょうか。

Aベストアンサー

VB6アプリケーションは、Windows7でも動作可能です。
ただし、サードパーティ製のActiveXコントロールを利用している場合は、
その限りではありませんが。

ActiveXコントロールが不足してたりしませんか?
ActiveXコントロールを含めたインストーラーを使ってインストールしていますか?

EXEをコピーしただけで動かないと言っているのであれば、
WinXP(もちろんWin98でも可)あたりにVB6を入れて、インストーラーを作成して下さい。

もしくは、ActiveXコントロールをインストールする為のダミーのツールでもインストールすれば良いかな。

こんなの
http://www.vector.co.jp/soft/win95/util/se188840.html

QVBの「As String * 128」とは?

VBの「As String * 128」とは?

Visual Basic 2010 Expressでコンソールアプリケーションを作成しています。

OSのヴァージョンを取得する機能を作成したかったので、

http://hanatyan.sakura.ne.jp/vbhlp/Version.htm

を参考にして、OSVERSIONINFOの構造体を定義しました。

しかし
szCSDVersion As String * 128

「* 128」
の部分で、ステートメントの終わりを指定してくださいとエラーが出ます。

「* 128」とは、いったいどういう意味ですか?

また、エラーを無くす方法はありますか?

いろいろ検索しましたが、調べ方が悪いのか、分かりませんでした。

よろしくお願いします。

Aベストアンサー

参考にされたサイトはVB6.0用のソースですね。
VB6.0とVB2010(=VB.NET)は色々な部分が変わってますので、VB.NET用のサンプルを見た方が良いと思います。

http://dobon.net/vb/dotnet/system/osversion.html

ちなみに一応、質問に答えると…

> 「* 128」とは、いったいどういう意味ですか?

VB6.0(VB2010の5世代前のバージョン?)で固定長文字列を表す定義です。
* 128と記述すると128文字以上の文字列を入れても自動的に128文字でカットされます。

> また、エラーを無くす方法はありますか?

VB2010(=VB.NET)では以下のように記述します。
<VBFixedStringAttribute(128)> Private szCSDVersion As String

QForm_Load と Form_Activate のタイミング

あるデータ入力アプリを作っています。
親フォーム(Form0)で番号を決め、子フォーム(Form1,Form2,Form3,Form4) でデータ入力し、それぞれの子フォームを出るとき(Unload Me) に、変数にsaveしています。それを親フォーム(Form0)で登録を選択したとき、入力データをチェックしてDBに格納しています。
すでにDB格納済のデータの場合、親フォームでDBから変数に読み込み、子フォームのForm_Loadで展開しています。
そこで困っているのは、親と子のフォームを行き来するときにデータの表示で前のが残っていたり、消えてしまったりします。
Form_LoadとForm_Activateを通過するタイミングが、ちゃんと理解できていないためコードの記述位置が不適切なのだと思います。

Form_Load と Form_Activate の実行タイミングについて、お教えください。

Aベストアンサー

Form_Loadは、フォームがロードされたときです。
ロードされる条件は、
1.フォームがスタートアップに指定されているとき、アプリが実行された直後。
2.Show メソッドが呼ばれたとき
3.Loadメソッドが呼ばれたとき
4.フォームに貼り付けられたコントロールのプロパティが参照されたとき
5.フォームに貼り付けられたコントロールのメソッドが呼ばれたとき
です。

ただし、一度ロードされると、Unloadされるまで呼ばれません。


Form_Activateは、フォームがアクティブになったとき、つまり、キャプション(ウィンドウのタイトルバー)の色が変わったときです。

QConsole.WriteLine で表示されない

VB2008でプログラムミングしておりますが、プログラミング試験の為によく使われる、「Console.WriteLine」ですが、表示されないのです。
何処に表示されるのでしょうか。
デバックを行っても何処にも表示されません。

Console.WriteLine("Hello World")
でも表示が何処にも有りません。

初歩的な質問ですが、私には大事な一歩なので宜しく御願い致します。

Aベストアンサー

質問者さんはもう見ていないかもしれませんが、一つ。
質問者さんはプロジェクトのタイプをFormにしているので、コンソールに表示されないのです。
プロジェクトのタイプをコンソールアプリケーションにすれば良く見られるDOS窓に表示されます。
Formアプリケーションタイプでも、確かプロジェクトのプロパティをいじればできたはずです。

Q動作を停止しましたと表示され、停止します。

動作を停止しましたと表示され、アプリケーション停止します。

問題の詳細



発生元
怪盗攻略ブラウザ2

概要
動作が停止しました

日付
‎2013/‎08/‎07 0:19

状態
レポートが送信されました

説明
障害が発生しているアプリケーションのパス: C:\Users\******\AppData\Local\Apps\2.0\8B9RETX1.HAB\QDOQORNC.VKJ\kait..tion_8149fee0edf1ff73_0002.0001_5674af9cba542bd5\KaitoBrowser2_1.exe

問題の署名
問題イベント名: APPCRASH
アプリケーション名: KaitoBrowser2_1.exe
アプリケーションのバージョン: 1.0.0.0
アプリケーションのタイムスタンプ: 51ef9c9c
障害モジュールの名前: KERNELBASE.dll
障害モジュールのバージョン: 6.1.7601.18015
障害モジュールのタイムスタンプ: 50b83c8a
例外コード: 4000001f
例外オフセット: 00013219
OS バージョン: 6.1.7601.2.1.0.768.3
ロケール ID: 1041
追加情報 1: 12e5
追加情報 2: 12e5e8e1c146c520e06bac21034ebc4f
追加情報 3: 3670
追加情報 4: 367002d938052abab76c4a26ecb98de3

この問題に関するその他の情報
バケット ID: 3728007683

動作を停止しましたと表示され、アプリケーション停止します。

問題の詳細



発生元
怪盗攻略ブラウザ2

概要
動作が停止しました

日付
‎2013/‎08/‎07 0:19

状態
レポートが送信されました

説明
障害が発生しているアプリケーションのパス: C:\Users\******\AppData\Local\Apps\2.0\8B9RETX1.HAB\QDOQORNC.VKJ\kait..tion_8149fee0edf1ff73_0002.0001_5674af9cba542bd5\KaitoBrowser2_1.exe

問題の署名
問題イベント名: APPCRASH
アプリケーション名: KaitoBrowser2_1.exe
ア...続きを読む

Aベストアンサー

追加
>KERNELBASE.dll

VB***、.NET Framework*関連の場合もあります。
VB PowerPacksSetup.exeを実行インストールして解決した事例
参考URL

参考URL:http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=al2&namber=30385&no=0&KLOG=3

QVBプログラムの終了

VB6.0で作成した実行ファイル(exe)を終了させても
タスクマネージャのプロセスに残ってしまい、
もう一度プログラムを起動することができません。
(プログラムで二重起動防止の処理をしています)

このプログラムをVBのラインタイムが入っていない
マシンで動かしているのですが、
やはりそれが問題なのでしょうか?
それとも別に何か原因があるのでしょうか?

Aベストアンサー

正常動作ならば、終了させれば プロセスも閉じられます。

VBのランタイムが 入ってない場合、異常終了で、ちゃんと終了してないと思われます。

QDoEvents関数って何?

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら

for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。

しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」

と書いてあるのですが正直、書いてあることがよくわかりません。

どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?

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

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そ...続きを読む

Aベストアンサー

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
    DoEvents
    Cells(i,1) = ""
  Next i
End Sub

Private Sub CommandButton2_Click()
  MsgBox "hoge"
End Sub

っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。

これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。

Private Canceled As Boolean

Private Sub CommandButton1_Click()

  CommandButton2.Enabled = False

  Dim i As Long
  For i = 1 To 50000
    DoEvents

    If Canceled = True Then
      MsgBox "キャンセルしました"
      Exit Sub
    End If

    Cells(i, 1).Value = ""
  Next i
End Sub

Private CommandButton2_Click()
  Canceled = True
End Sub



コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
...続きを読む

QVB6のアプリケーションの配布

VB6でアプリケーションを作成したのですが、他のマシンに配布する場合に実行形式(EXE)だけだと、DLLやOCXなどの有無やバージョンの違いで動作しないのですが、Setup.exeなどダブルクリックするだけで、インストールできるようにしたいですが、方法がわかりません。
VBのランタイムは、このSetup.exeより先にインストールしないと、Setup.exe自体でインストールが中断されるのでしょうか?

あと、.NETですがVB6のようにDLLやOCXの有無・バージョン違いなど気にせず簡単に配布できるのがメリットの一つと解釈しても良いのでしょうか?

このように配布・インストール関連で詳しい書籍などご存知でしたら教えてください。
インストーラソフトというものは言葉聞いたことがあるのですが、
.NET使うならば、あまり必要ないのでしょうか?これもお勧めのインストーラソフトがあるのでしたらご教授下さい。

Aベストアンサー

殆どのVB製フリーソフトでは別途ランタイムをインストールしてくださいで済ましているようですが。
どうしても組み込みたいということでしたら、インストーラーの作成時に組み込みましょう。殆どの人はそれで問題がおきる(低バージョンのDLLでの上書きとか)ことが予想されるため、ユーザー任せにしているわけで。
>Setup.exe自体でインストールが中断
そのインストーラー自体が特定のDLLやOCXに依存して作っているのなら先に必要となりますが、殆どのケースでは必要ないように作られるかと思います。どうやって作ったのか次第です。

.NETの場合は、これらのVB時代の反省を生かして所謂ランタイム的なものを.NetFrameWorkとしてマイクロソフトが一元管理しています。そのため.NdetFrameWorkのバージョンが1.1なり2.0を入れておいて下さいとするだけで(またそのインストールがWindowsUPDATEから可能)特に作成者側が気を回す必要はなくなりました。

VB時代も含めてのインストーラーの参考URL
http://dobon.net/vb/installer/index.html

殆どのVB製フリーソフトでは別途ランタイムをインストールしてくださいで済ましているようですが。
どうしても組み込みたいということでしたら、インストーラーの作成時に組み込みましょう。殆どの人はそれで問題がおきる(低バージョンのDLLでの上書きとか)ことが予想されるため、ユーザー任せにしているわけで。
>Setup.exe自体でインストールが中断
そのインストーラー自体が特定のDLLやOCXに依存して作っているのなら先に必要となりますが、殆どのケースでは必要ないように作られるかと思います。どうやっ...続きを読む

Qvb.netで作成したexeファイルが実行できない

vb.netのexeファイルでのアプリの一部の動作ができません。

プロジェクトファイルを開いて実行すれば稼動するのですが、生成したexeファイルを実行した場合に一部の動作が稼働できません。その動作以外の動作は稼働します。

その稼働しない動作はデバイスの状態変更(有効から無効)にする動作です。

原因が分かる方、推測できる方がいらっしゃったら、教えていただけないでしょうか?
宜しくお願いします。

exeファイルは監視exeでデバイスの接続時にフォームが表示するようにタスクスケジューラーで常時監視をしています。

また、通常時は画面上には見えないように「ShowInTaskbar」をFalseにしており、フォームは通常時最小化されている状態になります。

Aベストアンサー

>その稼働しない動作はデバイスの状態変更(有効から無効)にする動作です。

デバイスに停止命令を送っているAPI関数から、どういう戻り値が返って来るか表示してみましょう。

「デバイスに対するアクセス権なし」とか「デバイスに対するファンクション番号エラー」とか、色々なエラーが返されている可能性があります。

それ以前に、API関数が正常終了したかエラー終了したかくらいは調べましょう。

あと、もしかしたら「無効化しても、勝手にすぐに有効化しちゃってる」と言う可能性も捨て切れませんし、そもそも「無効化できないデバイス」なのかも。


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

人気Q&Aランキング