2002/10/15作成

 ちょっとした技

 ■ORA-12541 TNS:リスナーがありません

 Net8 Assistantで設定をしテストを実行すると接続されるが、SQL Plusで接続しようとすると
ORA-12541 TNS:リスナーがありません
のメッセージが出て接続できない。

 動作環境 OS :WinNT4.0 Workstation SP6
      Oracle:Oracle8i R8.1.7

 エラー・メッセージのマニュアルによると %ORACLE_HOME%\network\ADMIN\tnsnames.ora に記述ミスがあるようなことが書いてありました。
 しかし納得いかないのが設定はNet8 Assistantで行い、この中の接続テストではちゃんと接続できることです。それなのにSQL Plusからだと接続できない。ちなみに他のPCではNet8 Assistantで設定して、かつSQL Plusでも接続できてます。Net8 Assistant操作上でどこが違っていたのか、さっぱり分からないんですが、以下の方法で問題は回避できました。

動いたときの%ORACLE_HOME%\network\ADMIN\sqlnet.ora の内容

# SQLNET.ORA Network Configuration File: D:\oracle\ora81\network\admin\sqlnet.ora
# Generated by Oracle configuration tools.

NAMES.DEFAULT_DOMAIN = nihon-eng.co.jp

SQLNET.AUTHENTICATION_SERVICES= (NTS)

NAMES.DIRECTORY_PATH= (TNSNAMES, HOSTNAME)


 これのNAMES.DIRECTORY_PATHを修正しました。もとは
NAMES.DIRECTORY_PATH= (HOSTNAME)
だったんですが、TNSNAMESを追加してあげたらSQL Plusからもうまく接続できるようになりました。
 参考までにtnsnames.oraの内容は

%ORACLE_HOME%\network\ADMIN\tnsnames.ora の内容

# TNSNAMES.ORA Network Configuration File: D:\oracle\ora81\NETWORK\ADMIN\tnsnames.ora
# Generated by Oracle configuration tools.

SVR2.NIHON-ENG.CO.JP =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.101)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = kensyuu.nihon_eng.co.jp)
    )
  )

SVR1.NIHON-ENG.CO.JP =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.100)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = kensyuu.nihon_eng.co.jp)
    )
  )

というように、2つのDBサーバーを設定してあります。



 ■EXCEL(VBA)HELPの表示方法

 EXCELでVBAのヘルプを表示する場合Visual Basic Editor上でメニューからヘルプを選んでMicrosofr Visual Basicヘルプを表示するのではなく、EXCELの方でメニューからヘルプを選んでMicrsoft Excelヘルプをを表示したほうがいいです。
 目次の中に「Microsoft Visual Basicリファレンス」があるので、こちらから表示しましょう。Visual Basic Editorから表示した場合と比べ、目次に表示される内容がだいぶ違います。
 特にEXCELの方でメニューからヘルプ表示 − 目次でMicrosoft Visual Basicリファレンスを選択 − この下にある Microsoft Excel のオブジェクト は何かと便利です。



 ■EXCEL ユーザーメニューの追加

 以下のような処理を Private Sub Workbook_Open か Private Sub auto_Open の中に記述しておけば、そのEXCELブックを開くとメニューバーにユーザーメニューを追加することができます。

ユーザーメニュー追加処理部分

    Dim W_CurMenuBar       As CommandBar         ' 現在のEXCELメニューバー
    Dim W_MenuBar          As CommandBarControl  ' ユーザーメニュー追加後のメニューバー
    Dim W_CtlButton        As CommandBarButton   ' ユーザーメニューに追加した項目ボタン
    

    'デフォルトのEXCELメニューバーに戻す
    On Error Resume Next
    CommandBars.ActiveMenuBar.Reset
    On Error GoTo 0
    
    'メニューに「ユーザーメニュー」を追加
    Set W_CurMenuBar = CommandBars.ActiveMenuBar
    Set W_MenuBar = W_CurMenuBar.Controls.Add _
        (Type:=msoControlPopup, _
         Temporary:=True, _
         ID:=1)
    With W_MenuBar
        .BeginGroup = True
        .Caption = "ユーザーメニュー"
        .Visible = True
        .Enabled = True
    End With
        
    ' 「ユーザーメニュー」に、個々のサブメニューを追加していく
    Set W_CtlButton = W_MenuBar.Controls _
        .Add(Type:=msoControlButton, Temporary:=True)
    W_CtlButton.Caption = "サブメニュー1"
    W_CtlButton.Style = msoButtonCaption
    W_CtlButton.OnAction = "FuncSubMenu1"
    
    Set W_CtlButton = W_MenuBar.Controls _
        .Add(Type:=msoControlButton, Temporary:=True)
    W_CtlButton.Caption = "サブメニュー2"
    W_CtlButton.Style = msoButtonCaption
    W_CtlButton.OnAction = "FuncSubMenu1"
    
    Set W_CtlButton = W_MenuBar.Controls _
        .Add(Type:=msoControlButton, Temporary:=True)
    W_CtlButton.BeginGroup = True
    W_CtlButton.Caption = "サブメニュー3"
    W_CtlButton.Style = msoButtonCaption
    W_CtlButton.OnAction = "FuncSubMenu1"

 個々のサブメニュー設定で W_CtlButton.OnAction に、Public Function 定義したメニューに対応する関数名を指定します。
 "ユーザーメニュー"追加時と"サブメニュー3"追加時に .BeginGroup = True を指定していますが、こうすると区切り線を表示することができます。

 後は Private Sub Auto_Close の中で

ユーザーメニュー追加処理部分

Private Sub Auto_Close()

    Application.ScreenUpdating = False
    
    'デフォルトのEXCELメニューバーに戻す
    On Error Resume Next
    CommandBars.ActiveMenuBar.Reset
    On Error GoTo 0
        
End Sub

としておけば、そのブックを閉じればデフォルトのメニューバーの状態に戻ります。
Set W_MenuBar = W_CurMenuBar.Controls.Addのときに、Temporary:=Trueにしておけば「コンテナ アプリケーションの終了と同時に自動的に削除されます」とのことなので、ブックを閉じれば削除されるのかと思ったんですが、そうでもないようです。Auto_Closeでの削除処理は入れておきましょう。



 ■EXCEL フォルダの取得

 VBAの中であるディレクトリ(フォルダ)を指定して、そのフォルダ以下の全ファイル(サブフォルダ含む)を処理したい場合です。フォルダの指定のためにダイアログを表示して、そこから情報を取得したいときですが、 GetOpenFilenameメソッドだと必ず何らかのファイルを指定するまで戻ってきません。ファイル名を持ってきてそこからパスを拾ってもいいんだけど、指定したいフォルダ内にはサブフォルダだけでファイルが無い場合に困ります。
 そうした場合にはGetSaveAsFilenameメソッドを使いましょう。これもファイル名を持ってくるだけで、実際の保存はされません。InitialFilenameパラメータに"Dummy"でも適当に指定しておけば、ダイアログではフォルダだけを指定できます。

ダイアログを表示してフォルダを取得処理部分

    Dim W_BaseDirName      As Variant      ' 検索開始ディレクトリ
    Dim W_FileSys          As Object       ' ファイルシステムオブジェクト
    Dim W_FolderObj        As Object       ' フォルダオブジェクト

    W_BaseDirName = Application.GetSaveAsFilename( _
                        InitialFilename:="Dummy", _
                        Title:="一覧作成開始フォルダを選択")
    
    If W_BaseDirName <> False Then

        Set W_FileSys = CreateObject("Scripting.FileSystemObject")
        Set W_FolderObj = _
            W_FileSys.GetFolder(W_FileSys.GetParentFolderName(W_BaseDirName))
                
        ' フォルダやファイルを使った処理を記述

    End If




このページの先頭  技術メモ先頭

Copyright © 2002 YOK. All Rights Reserved.