W2k+VB6にて開発しております。
シリアル通信におけるCOMポート制御についての質問なのですが、
ポートをOPENしようとすると「ポートは既に開かれています」というエラーが出てしまいます。
--------------------------------------
if me.comm1.portopen = False then
me.comm1.portopen = True
end if
--------------------------------------
としているにもかかわらずOPENできません。
このような場合どういった要因が考えられるのでしょうか?
よろしくお願いします。

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

A 回答 (3件)

No.1の方の補足です。


mk_jmcさんが書かれたようにプログラムを書いても、
別のアプリが同じ番号のCOMを使用しているときは、
VBはそのようなエラーメッセージを返します。
これは経験があります。

これは想像ですが、上記のようにプログラムを書いた場合、
VBは自分のプログラムがopenしたCOMポートはチェックできても、
他のアプリがopenしたCOMポートまではわからないのではないでしょうか。
もしそれをチェックしようとすると、APIを使うか(やり方までは不明)、
エラー処理で行うかということになります(On Error GoTo文)。

どのアプリがCOMを開いているかは、PC環境によるのでわかりません。
モデムもしくは何らかの常駐ソフトか...
今時シリアルマウスということはないでしょうね。
    • good
    • 0

若干参考になると思うサイトです。



参考URL:http://isweb8.infoseek.co.jp/school/speana_1/vb/ …
    • good
    • 0

別のアプリがCOMを使っているとか・・・

    • good
    • 0

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

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

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

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

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

QMSCommを用いたRS-232-Cデータ転送

Visual Basic ver.6を用いてRS-232-Cデータ転送のプログラムを書いています。
転送には,MSComm controlを用いています。
コンピューター側から命令コードを測定器側に送信すると(例えば,MSComm1.OutPut = "F,3,300," & Chr(13)のように),測定器側からは次のようなテキストデータの転送が指定された回数だけ起こります:

@C/R
数値データC/R
数値データC/R
・・・・
・・・・
(指定回数繰り返す)

そこで,質問ですが,このデータをMSComm1.Inputを介してきちんと取得する方法をお教えください。私がよく理解できいない部分は,「どのような形でbufferにデータが落ちているのか?」という部分と「繰り返し処理をどう記述するのか?」という部分です。多分後者は配列型変数を用いて「指定回数」だけ繰り返すことになると思いますが・・・・。
なお,データ転送の制御フォーマットはデータのみの転送で,STXもETXも使用していません。

Aベストアンサー

こんばんは。

これで、試してみてください。
'<<送信側>>
Private Sub Command1_Click()
MSComm1.InputLen = 0
MSComm1.PortOpen = True
MSComm1.Output = Text1.Text + Chr(13)
MSComm1.PortOpen = False
End Sub

'<<受信側>>
'起動時にポートを開いておきます。
'Timer1を貼り付けてIntervalを100程度に。
Private Sub Timer1_Timer()
Dim strBuf As String
strBuf = MSComm1.Input
If Len(strBuf) <> 0 Then
List1.AddItem strBuf
End If
End Sub

もし、受信データ長が同じ長さなら、OnCommイベントで
データ取得した方がいいのですが・・・

Qシリアル通信エラー

VBのMSCommにてシリアル通信アプリを作成しました。
デスクトップPC(Win2000)では正常に動作するにも関わらず、
ノートPC(WinMe)ではデータ受信時にとりこぼしが発生する様です。
とりあえず、MSCommのOnCommイベントプロシージャ内でCommEventプロパティにて
エラーコードを引っ掛けると、1006(ポート オーバーランです。ハードウェアから 1 文字が読み取られる前に、次の文字が受信されたため、先の文字は失われました。)というエラーが返却されます。
デスクトップPCでは何日か継続して通信させておいても、全くこのエラーが出ないのに
ノートPCでは数秒~数分で頻繁に発生します。
このエラーの意味について調査したのですが、様々なHPを見ると、FIFOバッファ(通常16バイト)のエリアが一杯になり、前にかかれていたデータが上書き
されたという事ではないかという所に辿り着きました。そこで、デバイスのポート設定の詳細
にて受信バッファを低レベル(1バイト受信毎にCPU割り込みを発生)にする事により、なるべく
FIFOバッファの余裕を持たせる設定にすれば、問題は解決あるいは頻度の減少を期待出きる
と思い、設定したのですが、結果は全く変わりませんでした。そこで質問です。
1)このエラーの意味は本当にFIFOバッファのオーバーランなのでしょうか。
2)もし、そうであるならば、解決策はあるのでしょうか?  フロー制御で回避出きる問題ではありませんよね?
3)このFIFOバッファあたりの調査が可能なツールはありますでしょうか?出きれば、本当にFIFOバッファが一杯になる現象がデータとして取得出きればうれしいのですが。

現在、MSCommの設定としては以下の通りです。
Settings=115200,N,8,1
InBufferSize=3000
Handshaking=2

以上、1)~3)すべてでなくても構いません、よろしくお願いします。

VBのMSCommにてシリアル通信アプリを作成しました。
デスクトップPC(Win2000)では正常に動作するにも関わらず、
ノートPC(WinMe)ではデータ受信時にとりこぼしが発生する様です。
とりあえず、MSCommのOnCommイベントプロシージャ内でCommEventプロパティにて
エラーコードを引っ掛けると、1006(ポート オーバーランです。ハードウェアから 1 文字が読み取られる前に、次の文字が受信されたため、先の文字は失われました。)というエラーが返却されます。
デスクトップPCでは何日か継続して通信させ...続きを読む

Aベストアンサー

全てお察しの通りです。
おそらくWin2000マシンの方はパワーがあるので間に合っているが、Meマシンはパワー不足で間に合わず、フロー制御がかからないため、デバイス上のFIFOバッファを使い切り、そこでデータを喪失しているのでしょう。

バイナリーファイルのやりとりならソフトウェアフローは使用できませんね。相手側にもちゃんとハードウェアフローをしてもらうしかないでしょうし、それで解決するはずです。

それと、前回の回答でも書きましたが、ケーブルのせいかもしてないので、その辺はきちんと調査して切り分けてくださいね。

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
...続きを読む

Qデバイスマネージャーの一覧取得

デバイスマネージャーの一覧取得

VB2005,Framework2使用です。

現在PCで使用されているデバイスドライバ名を表示させたく、デバイスマネージャーに表示されているデバイス名を列挙し配列に収めたいのですが、調べてみたところSetup API等を使用すると可能な様ですが、VBではどのように記述すれば良いのでしょうか?

API利用までの知識がないのでここで凄く挫折しています・・



VBではありませんが、以下のサイトが参考になると思います。
参考:http://www.usefullcode.net/2006/12/post_19.html


よろしくお願いします。

Aベストアンサー

WMIのWin32_PnPEntityを使ってみるのはどうでしょうか?

Imports System
Imports System.Management ' 参照設定が必要
Module Module1
  Sub Main()
    Try
      Dim searcher As ManagementObjectSearcher
      searcher = New ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity")
      For Each queryObj As ManagementObject In searcher.Get()
        Console.WriteLine("{0}", queryObj("Name"))
      Next
    Catch ex As Exception
      Console.WriteLine(ex.Message)
    End Try
  End Sub
End Module

必要な情報は
http://www.anchorsystems.jp/anchor/ashp/netmon/samples/wmi_hard.html#Win32_PnPEntity.htm
を参考にしてみてください。

WMIのWin32_PnPEntityを使ってみるのはどうでしょうか?

Imports System
Imports System.Management ' 参照設定が必要
Module Module1
  Sub Main()
    Try
      Dim searcher As ManagementObjectSearcher
      searcher = New ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity")
      For Each queryObj As ManagementObject In searcher.Get()
        Console.WriteLine("{0}", queryObj("Name"))
      Next
    Catch ex As Exception...続きを読む

QVB6でシリアル通信サンプルソースの入手先は

お世話になっております、
VB6でシリアル通信(UART)を行うための、
サンプルソースをダウンロードできるサイトをご存知の方いましたら、
教えていただけないでしょうか。

有料やアプリは見つけたのですが、
無料のソースが見つけられませんでした、
希望としてはMSCommを使用している物をご紹介していただけないでしょうか

Aベストアンサー

Visual Studio 6 のサンプルプログラムの中に
「VBTerm」という通信プログラムが有ります。
(エディションによっては入っていないかも)

QVB RS-232C 通信プログラム

何度もお世話になっております。(VB6.0 MSCommを使用した通信プログラムを作成中です。)私は新卒で食品会社に入社したのですが,プログラムの分かる上司が身近では誰1人といない状況で困っています。

今作成しているのは,重量計に荷物が乗った段階で作業者がデータ転送ボタン(重量計についている)を押すと,重量計のデータ(500kgというデータ)をシリアルでCOM1に取り込み,フォームにエクセルのセルを作成し(OLEを用いて)保存できるようにしたいと考えています。

(重量計から送られてくるデータのフォーマット)
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8
S T , N T , + 0 0 1 2 . 3 4 k g CR LF
ST ; ヘッダ1 NT ; ヘッダ2  CRLF ; ターミネータ
                  の18バイトのデータです。

ここで質問なのですが
(1) 以下のプログラムで重量はバイト配列に受信できていますでしょうか?(実際に重量計とPCを接続できれば良いのですが工場の稼動状況が関わっておりすぐにはできません。)
(2) 18バイトのデータを受信するからと言って RThreshold = 18 として良いのでしょうか? 普通,データは1バイトずつ送られてくると思うので RThreshold = 1としてイベントを発生させる必要があるのかとも思うんですが。

'MSComm1,2(COM1,2)コントロールの初期設定
Private Sub Form_Load()
MSComm1.CommPort = 1 '通信ポートを設定
MSComm1.Settings = "9600,n,8,1" '通信条件の設定
MSComm1.RThreshold = 18 '固定長のデータ
End Sub

Private Sub Port1_Click() 'Port1_Clickのクリックイベントプロシージャ
If MSComm1.PortOpen = False Then 'シリアルポートのオープン
MSComm1.PortOpen = True
End If

LPort1.Text = "" 'テキストボックスのクリア受信

End Sub

Private Sub MSComm1_OnComm() '受信のOnCommイベント

Dim Buffer1(0 To 17) As Byte '受信バッファの変数宣言(18バイト)

Select Case MSComm1.CommEvent 'CommEventプロパティに対する処理
Case comEvReceive '受信データ有り

   Buffer1 = MSComm1.Input '受信データをバッファに格納

'これより下は受信した18バイトから必要なデータ8バイト目から4バイト分切り出し,dという配列(4バイト)に格納できないかと考えました。
Dim i As Integer

Dim d(0 To 3) As Byte

d = MidB(Buffer1, 8, 4)

LPort1.Text = d
'LPort1.Text = Buffer1 '受信データをテキストボックスに表示
End Sub

何度もお世話になっております。(VB6.0 MSCommを使用した通信プログラムを作成中です。)私は新卒で食品会社に入社したのですが,プログラムの分かる上司が身近では誰1人といない状況で困っています。

今作成しているのは,重量計に荷物が乗った段階で作業者がデータ転送ボタン(重量計についている)を押すと,重量計のデータ(500kgというデータ)をシリアルでCOM1に取り込み,フォームにエクセルのセルを作成し(OLEを用いて)保存できるようにしたいと考えています。

(重量計から送られてくるデータのフォー...続きを読む

Aベストアンサー

>★キャラクタ長 7bit
>★パリティ 偶数
のデータを
>★キャラクタ長 8bit
>★パリティ 無し
で受け取った場合、
LFが文字化けします。
そのため、“Case vbLf”は通りません。

※s = MSComm1.Input の後に
※MsgBox "s=" & s
※または
※MsgBox "s(hex)=" & Hex$(s)
※を入れて確認すればすぐに判ります。

Qエクセル VBA でのCOMポート認識

エクセルのVBAを使用してあるアプリを作成しています。そのアプリはシリアルポートを使用してある機器と接続する事で実現できます。
そこで質問ですが、当該PCが認識しているCOMポートをVBAのSELECT BOXに表示したいのですがどうやれば(どのような関数?)を使用して実装COMポートを認識するのでしょうか?
もちろん、USB<--->シリアルケーブルを使用した場合もCOMポートだと認識しなければなりません。
よろしくお願いいたします。

Aベストアンサー

こんにちは。

Windowsのプログラム(VBA含む)から、COMポートを扱う場合は、WindowsAPI を使用すれば可能
だと思います。

COMポートの実装チェックには、WindowsAPI の「CreateFile」関数でCOMポートのオープンを実行
して、その関数の戻り値がエラーかどうかを見れば判断できると思います。
ただし、COMポートが実装されていてもエラーになるケース(既に使用中、使用不可に設定されて
いるなど)がありますので、その場合はエラーコードを取得してその値で「実装/非実装」を判断しな
いといけないと思います。

以下に、VBA から WindowsAPI (COMポート制御関連を含む)を利用するに当たって、参考になり
そうなサイトを上げてみました。宜しければ覗いてみて下さい。

■参考サイト
注)リンク切れの際は御容赦下さい。

1)VBAでWindowsAPIを使用してシリアル通信を行う方法

◎WindowsAPI講座
http://www.serpress.co.jp/winapi/
・このページよりリンクされている下記項目「シリアル通信(1)~(4)」のページでVBAから通信関連の
 APIを使用する方法が書かれています。
 NO.12 シリアル通信(1) ←必要なWindowAPI定義の説明
 NO.13 シリアル通信(2) ←シリアルポートのオープンとクローズを説明
 NO.14 シリアル通信(3) ←シリアルポートの通信プロトコル、送受信バッファ、タイムアウトの設定
 NO.15 シリアル通信(4) ←シリアルポートの送受信方法を説明
・今回の場合は、
   シリアルポートのオープン → 存在有無チェック → シリアルポートのクローズ
 までを行えば良いようなので、シリアル通信(1)~(2) までを参照すれば良いと思います。

2)CreateFile関数でCOM10以上のCOMポートを使用する際の注意点

◎CreateFile関数(Win32API)でCOM10以上を使う場合の注意点
http://www.aofactory.net/log/eid328.html
・ここで、API関数「CreateFile」で指定するCOMポート名(COM1、COM2など)に「COM10」以上を使用
 する場合の問題点および対策が書かれています。
・指定するCOMポートのデバイス名の頭に "\\.\" を付ければ良いようです。
   VBAでの指定例: "COM10" の場合は、 "\\.\COM10" とする。

3)WindowsAPI利用でCOMポートの存在有無をチェックする方法

◎COMポートが存在するかどうかを調べるには? - OKWaveの過去ログより
http://okwave.jp/qa4033242.html
・ここで、API関数「CreateFile」が失敗した際に、同じくAPI関数「GetLastError」でエラーコードを見て
 COMポートの存在有無を調べる旨が書かれています。
注)ただし、VBAでは「GetLastError」を呼んでもエラーコードが得られない可能性があるので、下記4)
 の方法を採った方が良いようです。

4)VBA から Windows API を利用する方法など

◎Office VBA と Windows API - Microsoft MSDN より
http://msdn.microsoft.com/ja-jp/library/cc326057.aspx
・このページの「エラー情報の取得」の説明で、VBAからWindowsAPIを呼出した際のエラーコードの取得
 方法が書かれています。
・VBAからWindowsAPIのDLLを呼び出した際のエラー情報は、「GetLastError関数」では取得できない
 可能性があるので、VBAの場合は「Errオブジェクト」の「LastDLLErrorプロパティ」でエラーコードを取得
 すれば良いようです。
・今回の場合は、COMポートオープン時のエラーコード取得に、この方法が利用できると思います。

こんにちは。

Windowsのプログラム(VBA含む)から、COMポートを扱う場合は、WindowsAPI を使用すれば可能
だと思います。

COMポートの実装チェックには、WindowsAPI の「CreateFile」関数でCOMポートのオープンを実行
して、その関数の戻り値がエラーかどうかを見れば判断できると思います。
ただし、COMポートが実装されていてもエラーになるケース(既に使用中、使用不可に設定されて
いるなど)がありますので、その場合はエラーコードを取得してその値で「実装/非実装」を判断しな
いといけないと...続きを読む

QMScommのOncommイベントが発生しない

ACCESSでMScommオブジェクトを使用し、ある機器からデータの読み取りを行いたいのですが、肝心のOncommイベントが発生いたしません。
なにか、ライブラリの参照設定が必要なのですか?
それとも、自分の設定間違い(不足)なのでしょうか?
前にVBでMScommを使用したことがありますが、なにも特別なことはしなかったような・・・(MSCOMM32.OCXを使用しています)
補足が必要であれば、追記いたします。

Aベストアンサー

ケーブル確認
>ある機器
は、特殊なケーブル接続では?
クロス/ストレートを間違ってないか?
使用しているケーブルが断線していないか?

>なにも特別なことはしなかったような
 プロパティは、あっていますか?

Accessだけで、NGとは考えにくいです。

QVB6.0-整数と余りを求める

表題の通り、整数と余りを求める関数を教えてほしいです:例:100/60=1余り40
整数:1
余り:40
よろしくお願いいたします。

Aベストアンサー

Dim A,B,C,D as integer
A=100
B=60
C=Int(A/B) <---答は1
D=A mod B

●IntはAをBで割った時の整数部分を求める関数ですが、答が負の場合は
注意が必要です。 例 Int(-100/40)=-2
これを回避する場合 Fixがいいです

●mod は A を B で割った時の余りを求める関数

Qコンパイルエラー:ユーザ定義型は定義されていません、と出るのですがどのライブラリファイルかわかりません。

VB6で以前誰かが作ったプログラムの修正をしているのですが、コンパイルができません。

コンパイルエラー:ユーザ定義型は定義されていません。と表示されてしまします。

参照設定のライブラリファイルにチェックを入れればいいと思うのですが、どのライブラリファイルにチェックを入れればいいのかわかりません。
どなたか教えていただけないでしょうか?

現在チェックが入れてあるのは
Visual Basic For Applications
Microsoft Access 10.0 Object Library
OLE Automation
Microsoft Visual Basic for Applications Extensibility5.3
Microsoft DAO3.6 Object Library
の五つです。

ソースは以下のとおりです。

-------------------------------------------
Private Sub timTimer_Timer()
Dim objCmpct As PharmitCompact

timTimer.Enabled = False

Set objCmpct = New PharmitCompact
objCmpct.DatabaseFolder = App.path & "\Database"
objCmpct.DBCompactType = phrCmpTypeAll
objCmpct.Exec
Set objCmpct = Nothing

Unload Me

End Sub
---------------------------------------------
上のソースで
objCmpct As PharmitCompact
の部分の色がエラーで変化します。

原因が違っていたらごめんなさい。
どうぞよろしくお願い致します。

VB6で以前誰かが作ったプログラムの修正をしているのですが、コンパイルができません。

コンパイルエラー:ユーザ定義型は定義されていません。と表示されてしまします。

参照設定のライブラリファイルにチェックを入れればいいと思うのですが、どのライブラリファイルにチェックを入れればいいのかわかりません。
どなたか教えていただけないでしょうか?

現在チェックが入れてあるのは
Visual Basic For Applications
Microsoft Access 10.0 Object Library
OLE Automation
Microsoft Visual Basi...続きを読む

Aベストアンサー

#1です。


PharmitCompact型のクラスまたは構造体が、どこにあるかは
わかりませんが、どこかにコードがあるようですね。


人気Q&Aランキング