2009年06月28日

WindowsをCDだけで動かす

知人のパソコンのハードディスクがトラブった時に、何とかCD-ROMだけで起動できてハードディスクを読む方法はないかを検索したら「自分好みの緊急用ブートCDをつくろう! 〜Bart's PE Builder〜」というのを発見。
PE-Builder.jpg
よっしゃ!これでやってみよう!ということで、このサイトからリンクしてるいろんなサイトを見てとにかくCD-ROMだけで動く BartPE なるCDがとりあえず完成。

うぉ!動いた!おまけにハードディスクの中も見える!

ということで、外付けハードディスクに生き残ってるファイルをコピーしました。

でも結局、バックアップが一番大事exclamation×2
posted by ぜんこう at 08:42| Comment(0) | Windows

2009年06月27日

空白削除

VB での RTrim, Trimに該当する関数です。

trim.txt




#--------------------------------------------------------------------
# 右空白削除
# 概要 文字列の右空白を削除する
# 形式 $string = &RTrim ( $instring );
# 引数 $instring : in : 文字列
# 戻り値 右空白削除後の文字列
#--------------------------------------------------------------------
sub main'RTrim {
local ( $instring ) = @_;

$instring =~ s/\s*$//;
return $instring;
}

#--------------------------------------------------------------------
# 左右空白削除
# 概要 文字列の左右空白を削除する
# 形式 $string = &Trim ( $instring );
# 引数 $instring : in : 文字列
# 戻り値 左右空白削除後の文字列
#--------------------------------------------------------------------
sub main'Trim {
local ( $instring ) = @_;

$instring =~ s/^\s*//;
return &main'RTrim( $instring );
}
posted by ぜんこう at 18:07| Comment(0) | Perl

多階層ディレクトリの作成

多階層にわたるディレクトリを作成する関数です。

MultiMkdir.txt



#--------------------------------------------------------------------
# 多階層ディレクトリ作成
# 概要 多階層にわたるディレクトリの作成(mkdir)を一度に実行
# 形式 &MultiMkdir( $newdir );
# 引数 $newdir : in : 作成するディレクトリ
#--------------------------------------------------------------------
sub main'MultiMkdir {
my ( $temp, $pos );

local ( $newdir ) = @_;

do {
$temp = $newdir;
while ( 1 ) {
$! = 0;
mkdir( $temp, 0755 );
if ( $! == 0 || $! == 17 ) { # Normal or File Exist
last;
}
elsif ( $! == 2 ) { # No such file or directory
$pos = rindex( $temp, "\\" );
last if ( $pos <= 0 );
$temp = substr( $temp, 0, $pos );
}
else {
die "$main'me multi_mkdir : mkdir error : $!\n";
}
}
} until ( $temp eq $newdir );
}
posted by ぜんこう at 18:04| Comment(0) | Perl

Visual C++で作成したプログラムを実行すると「プログラム開始エラー」

Visual C++で作成したプログラムを実行すると「プログラム開始エラー」となる場合の対処方法です。


以下の2点をチェックしてみて下さい。

  1. フォルダ名や共有名に全角を使った場合に発生する場合もあるそうなんで、全角を使っていないフォルダ上では発生しないのであれば、それが原因
    ただし、どの全角文字が悪さをするのかは不明。

  2. Visual C++のランタイム関係のファイルが不足しているかもしれません。
    Vectorにある「MFC42.DLL & MSVCRT.DLL」<のページを参考に、ファイルをダウンロード&コピーしてみて下さい。

posted by ぜんこう at 18:02| Comment(0) | Visual C++

mdb, mde, adp, adeの判別方法

上記のファイル(mdb, mde, adp, ade)を判定するのに、ファイル名の拡張子で判断するのは実に格好悪い(笑)ということで、判定するロジックをご紹介します。

CurrentProject, CurrentDbCodeProject, CodeDb にしてもいいでしょうし、GetObject なんかを使えば、自分以外のファイルに関しても応用できると思います。
mdbmde の判定部分だけでしたら Access97でも使用できます。

ProjectTypeプロパティや GetObject のことなどは、RURI++さんに教えてもらいました。

access_db_type.txt



Dim strMDE As String

Select Case CurrentProject.ProjectType
Case acADP
On Error Resume Next
strMDE = CurrentProject.Properties("MDE")
If Err = 0 And strMDE = "T" Then
MsgBox "ADE です"
Else
MsgBox "ADP です"
End If
On Error GoTo 0
Case acMDB
On Error Resume Next
strMDE = CurrentDb.Properties("MDE")
If Err = 0 And strMDE = "T" Then
MsgBox "MDE です"
Else
MsgBox "MDB です"
End If
On Error GoTo 0
Case Else
MsgBox "不明"
End Select
posted by ぜんこう at 16:43| Comment(0) | Microsoft Access 2000

Accessデータベースをエクスプローラ上の右クリック(ショートカット メニュー)で最適化する方法

知ってる人は知っているんでしょうけど、エクスプローラでファイルを選択して右クリックした時に出てくるメニュー(ショートカット メニュー)ってカスタマイズできるんですね。実は私は知りませんでした。
そこで知らない人のために、ここに公開します(そんなオオゲサなもんか?)

(画像は Access97時代のものです ^^;)








  1. エクスプローラのメニューから[表示]〜[オプション]を選択し[オプション]ダイアログ ボックスを表示する
    [ファイル タイプ]タブを選択し、[登録されているファイルタイプ]で「Microsoft Access データベース」を選択し〈編集〉ボタンをクリック

rclick1.gif

  1. [ファイルタイプの編集]ダイアログ ボックスが表示されるので〈追加〉ボタンをクリック

rclick2.gif

  1. [新しいアクション]ダイアログ ボックスが表示されるので以下のように入力して〈OK〉ボタンをクリック


    アクション
    Compact
    別に CompactでなくてもOK

    アクションを実行するアプリケーション
    "C:\Program Files\Microsoft Office\Office\MSACCESS.EXE"
    /Compact /NOSTARTUP "%1"

    環境により MSACCESS.EXEのフォルダが違うかもしれません
    フォルダ名に空白を含む場合等、MSACCESS.EXEまでを " で囲まないとエラーになりますよ



rclick3.gif

  1. [ファイルタイプの編集]ダイアログ ボックスの[アクション]に追加した「Compact」が登録されました
    〈終了〉ボタンをクリックして終了します

rclick4.gif

  1. [オプション]ダイアログ ボックスを〈閉じる〉ボタンをクリックして終了

rclick5.gif

  1. エクスプローラで Microsoft Accessデータベース(拡張子 mdbのファイル)を選択し、右クリックしてみると「Compact」が追加されてます
    勇気のある人は実行してみましょう(笑)

rclick6.gif

posted by ぜんこう at 16:37| Comment(0) | Microsoft Access 2000

フォーム等のオブジェクトをシステムテーブルから抽出する方法

一般に(?)、Accessの各オブジェクトの一覧を取得するのに、以下のコレクションを使用していると思います。









オブジェクトコレクション
テーブルTableDefs
クエリーQueryDefs
フォームContainers("Forms").Documents
レポートContainers("Reports").Documents
マクロContainers("Scripts").Documents
モジュールContainers("Modules").Documents


オブジェクトの一覧をコンボボックスやリストボックスで使用する際、値集合タイプ(RowSourceType)「値リスト」にして、値集合ソース(RowSource)オブジェクト名を列挙することにより実現可能です。しかし、オブジェクト数が多かったり、名前が長かったりして、値集合ソース(RowSource)に(たぶん)2,048バイト以上を設定しようとするとエラーになってしまいます。

そこで、システムテーブルの MSysObjects から一覧を取得する方法をご紹介します。

テーブルからの抽出ですので、コンボボックスやリストボックスでは、値集合タイプ(RowSourceType)「テーブル/クエリー」にして、値集合ソース(RowSource)に以下のSQLを設定すればOKです。
SQL文で抽出していますので、コンボボックスやリストボックス以外にも、いろいろ応用できるんじゃないでしょうか?









オブジェクトSQL
テーブルSelect Name From MSysObjects
Where Type = 1 And BitAnd(Flags, -2147483646) = 0(i)(iii)
クエリーSelect Name From MSysObjects
Where Type = 5 And BitAnd(Flags, 1) = 0(ii)
フォームSelect Name From MSysObjects Where Type = -32768
レポートSelect Name From MSysObjects Where Type = -32764
マクロSelect Name From MSysObjects Where Type = -32766
モジュールSelect Name From MSysObjects Where Type = -32761


隠しオブジェクト(dbHiddenObject)を除外するには、各 Where句に And BitAnd(Flags, 8) = 0(iii) を付け加えて下さい。

  1. システムオブジェクト(dbSystemObject)を除外しています

  2. 理由は「TableDefs/QueryDefsコレクション中に作成した覚えのない TableDef/QueryDefオブジェクトが出てくることがある」を見てください。Access2000 でクエリー以外にテーブルでも予期せぬオブジェクトが出現したので、BitAnd(Flags, 1) = 0 (iii) を全ての SQL に入れたほうがいいかもしれません。

  3. SQLではビット演算してくれないみたいなんで関数を自作しました。



Public Function BitAnd(ByVal lng1 As Long, ByVal lng2 As Long) As Long
BitAnd = (lng1 And lng2)
End Function

posted by ぜんこう at 16:07| Comment(0) | Microsoft Access 2000

TableDefs/QueryDefsコレクション中に作成した覚えのない TableDef/QueryDefオブジェクトが出てくることがある

クエリー(QueryDefs)~sq〜~TMPCLP〜 という名前のゴミやオバケと思えるものが出てくることがあります。その原因を追求してました。
ただ、あくまで私の出した結論であって 100%正しいかどうかは疑問ですので、信じるかどうかは皆さんにお任せします。

さて、この変な名前のクエリーは Access95までは出現していませんでした。つまり、Access97になって出現したようです。

システムテーブル MSysObjects のフィールド Type = 5 のものがクエリーに関する情報らしく、フィールド Flags がクエリーの種類をあらわしていると思われます。また、Flags の値は QueryDefオブジェクトの Typeプロパティの値に一致しているようです。

参考までに、まともな(データベース ウィンドウに表示されている)クエリー(QueryDefオブジェクト)の Typeプロパティの値は...選択クエリーは 0 (dbQSelect)、削除クエリーは 32 (dbQDelete)、更新クエリーは 48 (dbQUpdate)、追加クエリーは 64 (dbQAppend)等...(カッコ内は VBAの組み込み定数)。

ゴミやオバケと思われているクエリーには 2種類ありました。

一つは Flags = 1 となっているゴミクエリーを削除した直後に出現しましたが、ファイルを閉じる等のタイミングだと思うんですが、勝手に消滅します。このクエリーの名前は ~TMPCLPxxxxx というような感じで作成されるようです。

もう一つが Flags = 3 となっているもので、ゴミでもオバケでもありませんでした(考え方によってはオバケと言えるかもしれませんけどね)。
具体的には、フォームやレポートのレコードソース(RecordSource)プロパティが(クエリービルダを使ったりして)SQL文になっている場合や、コンボボックス等のコントロールの値集合ソース(RowSource)プロパティが前述のレコードソース プロパティと同様に SQL文になっているような場合に出現します。
これらの QueryDefオブジェクトの名前(Name)は、以下のような命名規則だと思われます。










FormRecordSource に対応するもの~sq_fフォーム名
ReportRecordSource に対応するもの~sq_rレポート名
FormControlRowSource に対応するもの~sq_cフォーム名^sq_cコントロール名
ReportControlRowSource に対応するもの~sq_dレポート名^sq_dコントロール名


そして結論としては...「(本当の)クエリーの一覧を取得する場合はQueryDefsコレクションから QueryDefオブジェクトの Typeプロパティが 1 または 3 のものを除外する」ということです。

その後、Access2000テーブル(TableDefs)~TMPCLP〜 という名前のものが出てきました。でも上記クエリーの場合とは異なり Flags = 1 にはなっていないのです。でも他の正常な(?)オブジェクトでは Flags が偶数だったので、当面完璧と思える結論は...「Typeプロパティが奇数のものを除外する」ということです。
posted by ぜんこう at 15:43| Comment(0) | Microsoft Access 2000

Accessの「ファイルを開く」などのダイアログを表示する方法

Accessで「ファイルを開く」とかのダイアログって、Windows標準のものじゃありませんよね。これの表示方法をご紹介します。

flags の値の意味とか、詳しいことは何もわかっていません (^_^;)。

access_dialog.txt









宣言部

Private Type OfficeGetFileName_Info
hwndOwner As Long
szAppName As String * 255
szDlgTitle As String * 255
szOpenTitle As String * 255
szFile As String * 4096
szInitialDir As String * 255
szFilter As String * 255
nFilterIndex As Long
lView As Long
flags As Long
End Type

Private Declare Function OfficeGetFileName _
Lib "msaccess.exe" Alias "#56" _
(gfni As OfficeGetFileName_Info, _
ByVal fOpen As Integer) As Long
「ファイルを開く」の例

Dim tOgfn As OfficeGetFileName_Info

With tOgfn
.hwndOwner = Me.Hwnd
.szAppName = Me.Caption & vbNullChar
.szOpenTitle = vbNullChar
.szDlgTitle = "ファイルの選択" & vbNullChar
.szFile = vbNullChar
.szInitialDir = "C:\My Documents" & vbNullChar
.szFilter = "Microsoft Access (*.mdb,*.mde,*.mda)|" & _
"*.mdb;*.mde;*.mda||" & vbNullChar
.flags = &H2
If OfficeGetFileName(tOgfn, True) = 0 Then
MsgBox Left$(.szFile, InStr(.szFile, vbNullChar) - 1)
Else
MsgBox "キャンセル"
End If
End With
「名前を付けて保存」の例
「ファイルを開く」の例の以下の部分の、TrueFalse にすればいいです。

If OfficeGetFileName(tOgfn, True) = 0 Then

If OfficeGetFileName(tOgfn, False) = 0 Then
「フォルダの選択」の例

Dim tOgfn As OfficeGetFileName_Info

With tOgfn
.hwndOwner = Me.Hwnd
.szAppName = Me.Caption & vbNullChar
.szOpenTitle = vbNullChar
.szDlgTitle = "フォルダの選択" & vbNullChar
.szFile = vbNullChar
.szInitialDir = "C:\My Documents" & vbNullChar
.szFilter = vbNullChar
.flags = &H20
If OfficeGetFileName(tOgfn, True) = 0 Then
MsgBox Left$(.szFile, InStr(.szFile, vbNullChar) - 1)
Else
MsgBox "キャンセル"
End If
End With
posted by ぜんこう at 15:27| Comment(0) | Microsoft Access 2000

OpenArgs が Null に戻る

Access2000(でしか調べてませんが)で、フォームの OpenArgsプロパティを設定して開いた(DoCmd.OpenForm)にもかかわらず、なぜか Null に戻ってしまうという状況に遭遇したことがあります。

正式な文書も何も見つけたわけじゃないので、あくまで予想ですが、そのようになるフォームだけ、フォームのFilter と FilterOnOrderBy と OrderByOnプロパティを使用しています。どうも、このプロパティのどれか(全て?)を設定すると OpenArgsプロパティが Null に戻されてしまうということが発生するようです。


とりあえず、フォームの開く時(Open)イベントでフォームモジュールの共通変数に格納して、以降はその変数を参照するようにしてます。




Dim fvarOpenArgs As Variant '' OpenArgsプロパティ

(中略)

Private Sub Form_Open(Cancel As Integer)
fvarOpenArgs = Me.OpenArgs

(中略)

End Sub


もし何か情報をお持ちの方が居ましたら、発生原因を教えて下さい。
posted by ぜんこう at 15:24| Comment(0) | Microsoft Access 2000