2024年3月22日金曜日

古いファイルを消すすくリプト(Windows , vbs)

概要

Windows環境でバックアップを掃除するツール
バッチファイルとvbsの組み合わせでTask起動して使う想定です

使い方

CSCRIPT LogDelete.vbs D:\Folder days > backupexec.log
CSCRIPT LogDelete.vbs D:\Folder1\ 30 > bkfiledl.log
CSCRIPT LogDelete.vbs D:\Folder2\ 60 >> bkfiledl.log

コード

Option Explicit

'CScript myname.vbs %1 %2 %1=フォルダ , %2=日数

    Dim DeleteLogPath    ' 削除基準フォルダ
    Dim DelDayCount      ' 削除する判断を行う日数
    
    Dim fso              ' FileSystemObjects
    Dim oTargetFolder    ' Folder Objects
    Dim oFile            ' File Objects
    'dim objRE

    'Set objRE = CreateObject("VBScript.RegExp")
    
    DeleteLogPath = Wscript.Arguments.Item(0)        ' 引数としてフォルダを受け取る。ない場合には例外
    DelDayCount   = Wscript.Arguments.Item(1)        ' 引数として、削除する過去日数を受け取る。ない場合には例外
    'objRE.Pattern = "^" & Wscript.Arguments.Item(2) & "$"

    'Object Create
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set oTargetFolder = fso.GetFolder(DeleteLogPath)
    
    WSCript.Echo (Now & " >> 指定された日以前のファイルを削除する ")
    WScript.Echo ("処理対象ディレクトリ >> " & DeleteLogPath)

    'File Delete
    For Each oFile In oTargetFolder.Files
    	'If objRE.Test(oFile.Name) Then
	        If DateAdd("d",DelDayCount,oFile.DateLastModified) < Now Then
	            Wscript.Echo (oFile.Name & " **** " & oFile.DateLastModified)
	            oFile.Delete
	        End If
        'End If
    Next

2023年1月23日月曜日

Excelの行列を文字から数値へ (26進数変換 vba)

いわゆる26進数変換です
VBAでコード書いていると列や行の位置を指定する事がありますが、固定文字列でコーディングすると変更があった際に面倒なので
基本的には数字で定義しておいて、変化に強くしておきます。 
 実装、テスト済なのでそのまま貼ってお使いください。
テスト実装も記載済です



Option Explicit

Public Function ToBase26(ByVal self As Long) As String
    If self <= 0 Then
        ToBase26 = ""
        Exit Function
    End If
    
    Dim n As Long
    n = IIf((self Mod 26 = 0), 26, self Mod 26)
    
    If self = n Then
        ToBase26 = Chr((n + 64))
    Else
        ToBase26 = ToBase26((self - n) / 26) & Chr(n + 64)
    End If
    
End Function

Public Function FromBase26(ByVal self As String) As Long

    Dim charLength As Integer
    Dim i As Integer
    Dim steps As Integer
    
    If self = "" Then
        FromBase26 = 0
        Exit Function
    End If
    Dim result As Long
    
    Dim chars As Byte
    charLength = Len(self)

    For i = charLength - 1 To 0 Step -1
        Dim current As Integer
        chars = asc(Mid(self, i + 1, 1))
        current = CInt(chars) - 64      'ASC To 26
        If current < 1 Or current > 26 Then
            FromBase26 = 0
            Exit Function
        End If
        If (steps = 0) Then
            result = result + current
        Else
            result = result + (current * (26 ^ steps))
        End If
        steps = steps + 1
    Next

    FromBase26 = result
End Function

Public Function ToBase26Test()

    Dim i As Integer
    Dim tmp As String
    Dim ar As String
    For i = 1 To 2000
        tmp = ToBase26(i)
        ar = ar + tmp & vbTab
    Next
    
    Debug.Print ar

End Function

Public Function FromBase26Test()

    Dim tmp As Integer
    Dim i As Integer
    
    'ToBase26のテストがOKであれば本テスト実施可能
    
    For i = 1 To 2000
        tmp = FromBase26(ToBase26(i))
        If (tmp <> i) Then
            Debug.Print (ToBase26(i))
            Stop
        End If
    Next

    ' Stopしなければ全部OK


End Function

2022年9月21日水曜日

複数のExcelファイルのシートをひとまとめにする

必要に応じ都度作っている気がするのでテンプレとして残しておきます。 概略:複数のExcelファイルのシートを全部自分の場所へコピーしてくる 備考:エラーハンドリングなどはしてません
Option Explicit
Public Sub MergeDocuments()

    Const listIndex As String = "A"
    
    Dim i As Long
    Dim list As Collection
    Dim wk As String
    
    Dim currentwb As Excel.Workbook
    Dim currentws As Worksheet
    
    Dim wb As Excel.Workbook
    Dim ws As Excel.Worksheet
    
    Set list = New Collection
    
    'Step 1 シートの内容から対象ファイルのフルパスを取得する
    i = 1
    Do
        wk = ActiveSheet.Range(listIndex & CStr(i)).Cells(1, 1).Value
        
        If Len(wk) > 0 Then
        
            list.Add wk
        Else
            Exit Do
        End If
        i = i + 1
    Loop

    Set currentwb = ThisWorkbook
    Set currentws = ActiveSheet
    
    'Step 2 ファイルを順次開き、自分にコピーする
    Application.DisplayAlerts = False
    For i = 1 To list.Count
        wk = list(i)
        Set wb = Excel.Application.Workbooks.Open(wk, False, True)
        
        For Each ws In wb.Worksheets
            ws.Copy before:=currentwb.Worksheets(currentws.Index)
        Next
        wb.Close
        Set wb = Nothing
    Next

    MsgBox "Success"

End Sub

2020年6月8日月曜日

mysql(5.1) + カーソルloop使ったプログラムのテンプレ

たまに、ツールとしてデータベースプログラムを書くのですが、1から書くのではなく、いつもどこかの作成済みプログラムを流用しているので、流用も面倒くさくなり、テンプレ化することにしました。
他の人にも使ってもらえるよう、コメント多めです。

【概略】
データを取得して、繰り返しする処理のテンプレです。
データベースへの書き込み処理も考慮してトランザクションも記載してあります。

【コード】


-- プロシージャ入れ替え用のDROP
DROP PROCEDURE IF EXISTS PROCEDURENAME;
delimiter ///
CREATE DEFINER = `root`@`localhost` PROCEDURE `PROCEDURENAME`
 (IN param1 VARCHAR(10)
 ,IN param2 VARCHAR(10))
BEGIN
    -- Loop検知・保持する変数
    DECLARE done INT DEFAULT 0;
    -- 通常変数を記載する際にはカーソルの前に書く
    DECLARE local_aa VARCHAR(10);
    DECLARE local_bb VARCHAR(10);
    -- カーソル定義
    DECLARE l_cur CURSOR FOR select a ,b from xx; -- カーソル定義

-- データなしを検知するハンドラ
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
-- 例外を検知するハンドラ
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
    ROLLBACK;
    SET autocommit=1;
    SELECT 0 AS RESULT;
END;

-- メイン処理
-- オートコミットを切って、自立トランザクションにしています
    SET autocommit=0;
    START TRANSACTION;

-- カーソルを開く
    open l_cur;
-- 繰り返し処理
    REPEAT
-- 1件データ取得
        FETCH l_cur into local_aa , local_bb;
-- EOF判定
        IF NOT done THEN
            -- データ処理
            -- これを書いておくとコンソールにデバッグのように出力される
            SELECT now() AS CURRENT_DATETIME local_aa AS aa , local_bb AS bb;

            -- この例では別ストアドを呼ぶ
            call sub_procedure(param1,param2,local_aa,local_bb);
        END IF;

    UNTIL done END REPEAT;

-- 後片づけ
    close l_cur;

    COMMIT;
    SET autocommit=1;

-- 呼び出し元用に正常終了を返す    
    SELECT 1 AS RESULT;

end;
///
delimiter ;

【Tips】mysqlのfunctionでテキストの行数を数える

いつ何のために作ったか忘れたのですが、ごみ箱行きはもったいないのでここに残しておきます。

キーワード:
・テキストの行数を数える
・functionの作り方
・Loopの使い方



drop function if exists util_getRowCount;
DELIMITER ///
CREATE DEFINER=`root`@`localhost` function util_getRowCount(target longtext)
returns varchar(1000)
-- returns decimal(11,0)
BEGIN
    declare lineMaxCount    int;
    declare sLine           VARCHAR(100);
    declare retValue        decimal(11,0);
    declare lineCount       int;
    declare i               int;
    declare isComment       int;
    declare isBlank         int;
    declare lCodeCharCount  int;
    declare currentTarget   longtext;
    declare vDebug          VARCHAR(10000);
    -- 引数チェック
    if CHAR_LENGTH(target) = 0 THEN
        return 0;
    END IF;

    -- 変数初期化
    set i = 0;
    set lineCount = 0;
    set vDebug    = '';
    set lCodeCharCount = 0;

    -- 利用変数準備
    select CHAR_LENGTH(target) - CHAR_LENGTH(REPLACE(target,'\n','')) +1 into lineMaxCount;
    set currentTarget = REPLACE(target,'\r\n','\n');
    set currentTarget = REPLACE(target,'\r','\n');
    charLoopLabel: LOOP
        -- increment 
        SET i = i + 1;

        -- 抜ける条件
        IF i > lineMaxCount THEN
            LEAVE charLoopLabel;
        END IF;

        -- 行として判定する
        set sLine = replace(substring_index(currentTarget,'\n',1),'\t',' ');
        set isComment = 0;
        set isBlank   = 0;
        
        -- コメント判定
        if substr(trim(sLine),1,2)= '--' THEN
            set isComment = 1;
        end if;

        -- 空行判定
        if length(trim(REPLACE(sLine,'\t',''))) = 0 THEN
            set isBlank = 1;
        end if;

        if (isComment = 0 and isBlank = 0) THEN
            SET lineCount = lineCount + 1;
            set lCodeCharCount = lCodeCharCount + CHAR_LENGTH(sLine);
        end if;
        -- 判定した行を取り除く
        set currentTarget = substr(currentTarget,CHAR_LENGTH(sLine) + 2);
        
        -- set vDebug = CONCAT(vDebug,isComment,isBlank,'xx',sLine,'_');
    END LOOP charLoopLabel;
    return CONCAT(lineCount , ',' , lCodeCharCount);
    -- return lineCount;
    -- set vDebug = CONCAT(vDebug,'__result__',lineCount);
    -- return vDebug;

-- return CHAR_LENGTH(target);

end;
///
delimiter ;
-- select util_getRowCount('12345\n22345\n33345') AS '3';
-- select util_getRowCount('12345\n22345\n33345\n\n\n\n\n') AS '3';
-- select util_getRowCount('12345\n22345\n33345\n\n\n\n\n    -- comment \n -- comment2\n44444') AS '4';
-- select util_getRowCount('日本語\n日本語2\n日本語3\n\n\n\n\n    -- コメント1 \n -- comment2\n44444\n') AS '4';

2019年10月21日月曜日

【未解決】CSVダウンロードを行うと、ブラウザ(Edge)がクラッシュする

自社製品で発生した事象。未解決です。

事象

CSVダウンロードを行うと、ブラウザ(Edge)がクラッシュする

Windowsのアプリケーションログ

障害が発生しているアプリケーション名: MicrosoftEdge.exe、バージョン: 11.0.18362.418、タイム スタンプ: 0x5d995b38
障害が発生しているモジュール名: EMODEL.dll、バージョン: 11.0.18362.418、タイム スタンプ: 0x5d9957cb
例外コード: 0xc0000409
障害オフセット: 0x000000000035b4f4
障害が発生しているプロセス ID: 0x3edc
障害が発生しているアプリケーションの開始時刻: 0x01d584b9670fceb4
障害が発生しているアプリケーション パス: C:\WINDOWS\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe
障害が発生しているモジュール パス: C:\WINDOWS\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\EMODEL.dll
レポート ID: 04e20477-ddaf-4338-bfe2-39c8d13a63e3
障害が発生しているパッケージの完全な名前: Microsoft.MicrosoftEdge_44.18362.387.0_neutral__8wekyb3d8bbwe
障害が発生しているパッケージに関連するアプリケーション ID: MicrosoftEdge

確認したこと

ポップアップブロック →元々Off
Windows Defender SmartScan → OnだったのでOff
他のCSVダウンロード可能なサイトにてダウンロード → 正常にダウンロードできる

まとめ(途中報告)

これ以降、まだ詳しくは調べていませんが、現時点考えられる可能性は2つ。
1.自社製品がCSVダウンロードの処理でクライアントへ送っているレスポンスに不備
2.Edgeのバグ

1については開発者ツールで追えそうもないのでパケットキャプチャになりそう。
2については、まだネット上にも情報が足りないので、断定はできなさそう。

時期を見て、1については詳細調査を行いたいと思ってます。

2019年10月18日金曜日

【.netFramework】フォーム継承利用時のイベントハンドラの処理順

ある程度のシステムになると、基底フォームを作成して共通処理を実装し、個別は継承先のフォームで実装する。というケースが多くなると思います。

キーボードイベントの処理順がうまくいかないと技術者から聞かれ、過去の記憶を確認すべく、サンプル書いて確認しました。(サンプルコード(zip)は記事の一番下に置いてあります)

【結果】

OnKey****の場合、継承先から順番に処理される。(上書き用途)
Key****のイベントハンドラの場合、基底から処理される

なお、本検証結果は「一般的な実装方法を用いた場合」の結果であり、色々とコードで工夫をなさった場合にはこの限りではありません。例)On***系の実装でbase.On***を呼ばない。とか、基底のイベントハンドラを登録するタイミングを継承先で指定するなど、振る舞いを変える方法はあると思います。

【検証した方法】

1.以下3つのフォームを用意する
  ・基底フォーム (TestBaseForm)
  ・基底を継承したフォーム (InheritForm1)
  ・さらに継承したフォーム(InheritInheritForm2)
2.それぞれに、同じメソッド、イベントを実装
3.プログラムを実行して、順番を把握

【実装イメージ】

【テストコード】


/// 同じコードを継承先のフォームにも記載
public partial class TestBaseForm : Form
{
    string _myFormName = "TestBaseForm"; // ここは実装するフォーム名にする
    public TestBaseForm()
    {
        InitializeComponent();
        this.KeyPreview = true;
        this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form_KeyDown);
        this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Form_KeyPress);
        this.KeyUp += new KeyEventHandler(this.Form_KeyUp);
    }
    protected override void OnKeyDown(KeyEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
        base.OnKeyDown(e);
    }
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
        base.OnKeyPress(e);
    }
    protected override void OnKeyUp(KeyEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
        base.OnKeyUp(e);
    }
    private void Form_KeyDown(object sender, KeyEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
    }
    private void Form_KeyUp(object sender, KeyEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
    }
    private void Form_KeyPress(object sender, KeyPressEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("{0}:{1}", _myFormName, System.Reflection.MethodBase.GetCurrentMethod().Name));
    }
}

【実行ログ】

Log内容 Method 基底 継承1 継承2
InheritInheritForm2:OnKeyDown OnKeyDown    
InheritForm1:OnKeyDown OnKeyDown    
TestBaseForm:OnKeyDown OnKeyDown    
TestBaseForm:Form_KeyDown KeyDown    
InheritForm1:Form_KeyDown KeyDown    
InheritInheritForm2:Form_KeyDown KeyDown    
InheritInheritForm2:OnKeyPress OnKeyPress    
InheritForm1:OnKeyPress OnKeyPress    
TestBaseForm:OnKeyPress OnKeyPress    
TestBaseForm:Form_KeyPress KeyPress    
InheritForm1:Form_KeyPress KeyPress    
InheritInheritForm2:Form_KeyPress KeyPress    
InheritInheritForm2:OnKeyUp OnKeyUp    
InheritForm1:OnKeyUp OnKeyUp    
TestBaseForm:OnKeyUp OnKeyUp    
TestBaseForm:Form_KeyUp KeyUp    
InheritForm1:Form_KeyUp KeyUp    
InheritInheritForm2:Form_KeyUp KeyUp    

【まとめ】

フォームを継承して利用する際には、継承元に実装するロジックの用途、継承先での振る舞いを考慮したうえで実装を決めることをお勧めします。

【ソース】

20191018_KeyboardEventOrderTest_source.zip

2019年10月14日月曜日

WindowsUpdateでprintspoolerが起動しなくなった

保守案件です。Windows10で印刷ができなくなる事象に対する一部始終です。

【経緯】

・ある特定のPCでのみ発生。
・事象としては印刷ができない。
・ドライバなどを入れなおす。など試してみてもらってもダメ、SE保守となりました。

【把握できていること】

・プリンタスプーラサービス(Print Spooler)が停止している。
・サービスを手動で起動しても、暫くたつと停止してしまう。

【こちらで把握したこと】

・イベントビューアで、エラー状況を確認。2019/10/04よりPrintSpoolerがエラーを出しているようです。
・WindowsUpdateが最後に動いたのが2019/10/04
・ネットで「printspooler 停止してしまう windows10」で調べたところ、2019年9月4週に発信されたWindowsUpdateによる事象で、Microsoftも把握しているとの事。

【処置】

・WindowsUpdate  →「最新です」とはなっていたが、「最新を取得」でいくつかモジュールがインストールされました。OSの再起動を求められたので再起動
・WindowsUpdate(2回目)  →おなじく、「最新です」となっていたのですが、「最新を取得」でいくつかモジュールがインストールされました。1回目と同じで、net Frameworkのパッチなのが気になる。。。
・再起動後も現象は変わらず。 KB4524148を当てろ。という情報があり、当てようとしても、既にインストールされている。 https://www.catalog.update.microsoft.com/Search.aspx?q=KB4524148%20
・「KB4524148」で調べると新情報。 KB4524148をアンインストールしてください。と。

【結果】

・「KB4524148」をアンインストールすることで正常に動作するようになりました。

2019年9月18日水曜日

Google Pixel3に乗り換えて2週間使った感想

つい数日前、破格でPixel3を衝動買い。
前機種はXperiaXZで、購入後3年ほど経過していたのですがなかなか良い機種に出会ておらず、
今回大幅値引きとなっていたことがきっかけで、詳細確認せず購入しました。

2週間使って、諸々気づいたことがあるのでメモしておきます。
なお、始めに断っておきますが、Pixelそのものの評価ではなく、あくまでも自分の機種変更に対する主観です。(Xperia to Pixel)

はじめに

Android To Androidだからなのか、時代の流れなのか、Pixelを起動したら機種変更用のソフトウェアが入っていて、
旧スマートフォンとPixelをUSBで接続することにより、アプリ、データの移行を行ってくれました。
アプリの移行はともかく、アプリの認証情報などは移行できないだろうと思っていたら、
そこそこの数のアプリが認証情報(ログイン情報)も移行してくれていました。
ただ、すべてではありませんのでご注意を。Felica関連は一切移行しないので、手動での移行が必要です。


移行して良かったこと

指紋認証が便利

Xperiaは横面、Pixelは背面です。この背面が非常に便利。丁度持つ部分にセンサーがついてます。
複数の指を登録しておけば、ほぼストレスなくロックを解除できます。

充電が早い

メーカーのウリでもあるようですね。とにかく早いです。

スリムになった

あまり力を入れると折れるのではないかと思うくらい、スリムです。

Pixelに変えて困ったこと

キャストの仕様が変わった

元々、Miracast対応の機器にスマートフォンを接続して利用していました。
この機器にはPixel3はつながらないという事象。(具体的にはEZCastとFireTV)
FireTVはFireTV側にソフトを入れればOKということでインストールして対処。
EZCastは2週間たった現在、まだ解消法が見つかっていません。

MicroSDカードに対応していない

とはいえ、32GB -> 64GBなので、アプリ容量としては充分
USBも3.0に対応しているので、USBメモリでのデータ管理へ移行することにしました。

その他

対応していないアプリがいくつか移行できていませんでした。(対応していないのだから当たり前)
FeliCa のポートが前から後ろに変更。バンカーリングをつけて利用するためきちんと認識するか心配でしたが今のところ問題なく認識しています。

音声認識が賢くなった?利用していた入力ソフトが変わったせいかもしれませんが、便利になりました。

カメラが高性能みたいですね。(細かくは見ていない)

Gmailの検索を活用する(Tips)

今年に入り社内メールがgmailとなったので、自分なりに使っていて便利だったことをTipsとして残しておこうと思います。

話題の対象

Webでgmailにログインすると上部に出てくる「検索」の使い方です。(アプリでも同様かと思います:未検証)
なお、一部の演算子(記述方式)は、googleの検索でも使えます。

まずはじめに

Googleのヘルプで、使い方が載っています
https://support.google.com/mail/answer/7190?hl=ja
とはいえ、単一項の説明だけなので、組み合わせて使うことにより効果を発揮することも多いです。

基本的な使い方

  1. キーワードを入れれば、キーワード検索
  2. メールアドレスを入れれば、そのメールアドレスに対する送受信を対象。
  3. 複合キーワードの場合、スペースを入れる(AND検索)
  4. OR検索の場合、A OR B とする (ORは大文字で) もしくは、{ } で括る

よく使いそうな事例

あるメールアドレスからの受信のみを検索

from:メールアドレス
逆に、送信の場合、to:メールアドレス

ある特定のラベルが付与されたメール

label:ラベル名
例)label:処理済

ある特定のラベルを除外する

-label:ラベル名 -(マイナス)をつけるだけ。

添付ファイルのあるメールを検索

has:attachment

複数のラベルを検索

例){label:処理済   label:処理不要}  ※ORを使って両方出します

2019年8月16日金曜日

GroupSession という選択肢 (グループウェア)

社内で利用しているグループウェアが更改の時期となり、有償無償問わず探していたところ、無償で、かつOSSというグループウェアで導入しやすそうなものを見つけたのでメモしておきます。
※決して、この会社の回し者ではありません

【特徴(というか採用ポイント)】

・他のOSSと比べても、機能が多い
・OSSはフリー(無償)
・無償で利用できるにもかかわらず、ドキュメント等が充実
・カスタマイズも、アドオン形式の模様(未確実) →ということは本体のVerUPも適用可
・その他採用ポイントとして、
 ・無償版ダウンロード時の入力フォームへ諸々記載したが、返答のメールが丁寧だった
 ・社内にはサーバ、ミドル、アプリ改修ができる技術者がいる

【まとめ】

機能が多く、習得までには時間がかかりそうですが、細かな部分で画面からの設定による制御も可能となっていて、比較的スムーズに導入を開始できそうです。

興味がある方は以下リンクよりお試しください
https://groupsession.jp/

Visual Studio 2019 と nuget

ほぼ1行Tips

あるベンダからソース一式を受領してビルドしたところ、「参照コンポーネント 'xxxxxxxx' が見つかりませんでした。」のエラー

nugetで取れるはず。と再度試しても、「利用できません」と。

原因:オンラインの情報を参照する設定となっていなかった
処置:オプション→NuGetパッケージマネージャ→パッケージソース
   追加 → https://api.nuget.org/v3/index.json (名前は任意)

2019年5月29日水曜日

Accessの実装は整理整頓が大事(自己反省と雑記)

雑記です。

最近、ちょっとしたツールの作成にAccessを使いだしています。Accessといえば開発入門の時によく使っていましたが、仕事として業務システムを開発するには危なっかしいイメージがあり採用することはほとんどありませんでした。

今回、利用者1名でExcel管理に毛の生えたようなレベルのツールを作るためにAccess採用。作っていくうえでオブジェクトが増えすぎて煩雑になってきたので自戒の意味も込めてAccessを使う上での整理ポイントについて個人的な考え方をまとめておきます。

なお、ちゃんとしたシステムであれば、画面遷移図やら各種オブジェクトの一覧、設計書なども作るでしょうし、各種命名規約もきちんとしていると思いますので、今回のケースはそんなきっちりしないで「ざっと」作るときにでも注意しておいた方がいいですよ。というレベルの情報です。

【登場人物】
Access データベースファイル
フォーム、レポート、テーブル、VBAプログラム、マクロ

【これをやっておけば何とかなる】
命名はきちんとね。

【整理せずに進めて困る可能性がある事例(やらかしたこと含め)】
・テーブルの分類が不明
 マスタなのか、トランザクションなのか、ワークなのか
・フォームの用途が不明
 入力フォームなのか、処理フォームなのか、サブなのか
・レポートの呼び出し元が不明
 単体で呼び出せるが
・活きているオブジェクトなのか、試作なのか不明
・そもそもソース管理が

【これだけはやっておこう】

テーブル

接頭語くらいはつけましょう。必ず「作るときに実施」
後で変えてもAccessが良きに計らってリファクタしてくれるようですが、してくれない箇所もあります。(ソースへの記載は当然ながら変えてくれません)

フォーム

ある程度のカテゴライズは事前にしておきましょう。
考えられるカテゴリとしては
メニュー:画面遷移だけするもの
入力フォーム:データの登録、修正するもの
サブフォーム:入力フォームの中に組み込むもの
サブ画面:入力フォームのサブ機能をもつもの、処理指示など
個人的にはいわゆる「接頭語」と連番でまとまるのが良いと考えてます。

例) xxxxはわかりやすい日本語名
メニュー:FM連番xxxxxxx
入力:FI連番xxxxxx
サブフォーム:FI連番SUB連番xxxxxx
サブ画面:FS連番xxxxx

クエリ

作成する数も多いのでこれが一番散らかります。
【決めごと】
画面、レポートなどのオブジェクトに対応するものは同じ接頭語をつける。その後に詳細用途
例)
FI連番SxxxxxxForm
FI連番Sxxxxxxcboxxx ※セレクトボックス
FI連番SxxxxxxListxxx
FI連番Ixxxxxxx (Insertクエリとか)
FI連番SxxxxxxXXXXQuery

長くなっても、用途がわかった方が良い

共通はCOMxxxとかでいいんじゃないかな。
間違っても、日本語名だけではやらないこと。絶対にあとでわからなくなります。

クエリのネスト
クエリでクエリを参照することはあると思いますが、その時に命名をどうするかは悩ましい。私の場合には1処理でネストする場合のみSub1,Sub2とかで命名します。
既にあるフォームで作成しているクエリを参照したい場合、面倒であっても
作成済みクエリを直接参照するのではなく、新規クエリで作成済みクエリを参照するようにしています。

レポート

ID命名と、メインかサブかがわかればよいのではないでしょうか。
フォームから呼ぶのであればフォームと同じ連番をつけておけばOK

マクロ

個人的にはあまりなじみがありませんが、連番が合っていれば間違えないかと。

VBA

いわゆる個別処理か、共通処理かでモジュールは分けると思いますので
あとは一般的なコーディング規約でいいのではと思います。

まとめ

だらだらと列挙しましたが、結局のところ「命名」に尽きると思っています。
後で見た時、またはほかの人が見た時に相関性がわかるのが重要ですね。

余談

私の場合、ある程度作り込んだ後はデータとプログラムのファイルを分けてます。
プログラムのファイルからデータのファイルへリンクを張ることで実現。
プログラム改修などの際にはプログラムファイルだけを更新すればよいため利便性が高いです。

2019年5月22日水曜日

【注意喚起】佐川急便を騙った迷惑メールにご注意

佐川急便の不在通知を偽装した不正サイトへの誘導を受け取ったので、注意喚起のため記事にしておきます。

まとめ

あやしい情報を受け取ったら、「無視する」「ネットで調べる」「進む場合セキュリティに十分注意する」

#検索用キーワード 090-7447-6454 bt-ar.top 佐川急便 貨物追跡サービス apple.varifidogione.com

ことの経緯

普通に、社用の電話のSMSにメッセージが届きました。 ↓こんなの

bit.ly 自体は短縮アドレスなのでこの時点で怪しいことに気付くのは難しい。
携帯の番号をネットで検索しても、特に怪しい情報は見当たらない。

念のためスマホからのアクセスは警戒して、パソコンからアクセス(当然シークレットモードにして)。すると・・・


なんだ、佐川さんじゃないですか(この時点でドメインが怪しかったのに気づかずスルー)



ページを進めて確認してみると、アプリのインストール手順を教えてくれているんですね
提供元不明のアプリを許可せよ。と。まぁ最近はちょくちょくあるケースですね




さらに進む。貨物追跡サービスアプリか・・・。要らないなぁ



マニュアルはご丁寧。ん~。まぁ関係ないかな。必要あれば電話来るだろうし


っというわけで、スマホでも見てみるか。。。

ここまでで怪しかったこと

いくつかございます。間違え探しは後半にて


スマホでリンククリックしたら怒られました。(やっぱりそっち系だったか)

このケースの注意喚起は、ここで止まればまだ問題なく終えられる可能性があります。
この時点でアプリを強制終了。
警告画面の裏側には先ほど見ていた佐川急便のサイトらしきものが見えます。

その後色々調べてみた

この、apple.verifidogione.com というドメインも、謎のものでした。
この迷惑メールの正体を少しでも調べてみようと、PCサイトを再度確認




ドメイン登録を確認(bt-ar.top)


Domain Name: bt-ar.top
Registry Domain ID: D20190520G10001G_09522758-top
Registrar WHOIS Server: whois.bizcn.com
Registrar URL: http://www.bizcn.com
Updated Date: 2019-05-20T11:40:05Z
Creation Date: 2019-05-20T10:53:39Z
Registry Expiry Date: 2020-05-20T10:53:39Z
Registrar: BIZCN COM  INC
Registrar IANA ID: 471
Registrar Abuse Contact Email: abuse@bizcn.com
Registrar Abuse Contact Phone: +86.5922577888
Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
Domain Status: addPeriod https://icann.org/epp#addPeriod
Registry Registrant ID: 
Registrant Name: 
Registrant Organization: Sun Xiao Li


おもいっきし中国だし、5/20取得だしさらには



お知らせが2018-07とか、2018-08 だし

佐川急便さんのサイトを丸々コピーして構築したのでしょうね。

自分は半分引っ掛かりましたが、最近はこんなケースも出ているようです。
皆様お気をつけください。

追伸

佐川急便さんではすでに注意喚起をサイトへ掲示していました(クリックすると別ウインドウが開きます)
佐川急便を装った迷惑メールにご注意ください

2019年2月20日水曜日

MSSQLのDBが破損した模様

何かの理由で利用中パッケージソフトで新規登録ができなくなった模様。
※パッケージの問題ではない。と先にお伝えしておきます。

原因がDBだったので、問題を調べて、対処、処置まで完了したのでメモしておきます。

事の経緯

データを新規登録できなくなった。と連絡を受けました。
よく聞くと、登録ボタンを押すと「強制終了してしまう」との事
エラー内容を見る限りたぶんDB周りだろうな。と思い調査を開始しました。
ひとまず見つけたのはWindowsのアプリケーションログ。
「インデックスが壊れている可能性があります。DBCC CHECKDB を実行してください。」と出ていました

MSSQLのチェックツール


詳しい解説は以下サイトを参考としました。
https://www.ipentec.com/document/sql-server-db-repair-and-validation-with-dbcc-command
参考にしながら処置を実施

DBCC CHECKDB
GO

チェック結果を確認


メッセージ 8935、レベル 16、状態 1、行 1
テーブル エラー: オブジェクト ID 1413580074、インデックス ID 1、パーティション ID 72057594063093760、アロケーション ユニット ID 72057594068664320 (型 In-row data)。ページ (1:503) の前ページへのリンク (1:1503) は、親 (1:377)、スロット 31 がこのページに対して想定している前ページ (1:3646) と一致しません。
メッセージ 8978、レベル 16、状態 1、行 1
テーブル エラー: オブジェクト ID 1413580074、インデックス ID 1、パーティション ID 72057594063093760、アロケーション ユニット ID 72057594068664320 (型 In-row data)。ページ (1:503) に前ページ (1:1503) からの参照がありません。チェーン リンケージに問題がある可能性があります。
メッセージ 8935、レベル 16、状態 1、行 1
テーブル エラー: オブジェクト ID 1413580074、インデックス ID 1、パーティション ID 72057594063093760、アロケーション ユニット ID 72057594068664320 (型 In-row data)。ページ (1:1503) の前ページへのリンク (1:3646) は、親 (1:377)、スロット 84 がこのページに対して想定している前ページ (1:1251) と一致しません。
メッセージ 8936、レベル 16、状態 1、行 1
テーブル エラー: オブジェクト ID 1413580074、インデックス ID 1、パーティション ID 72057594063093760、アロケーション ユニット ID 72057594068664320 (型 In-row data)。B-Tree チェーン リンケージが一致しません。(1:1251)->next = (1:1503)、(1:1503)->Prev = (1:3646)。
メッセージ 8979、レベル 16、状態 1、行 1
テーブル エラー: オブジェクト ID 1413580074、インデックス ID 1、パーティション ID 72057594063093760、アロケーション ユニット ID 72057594068664320 (型 In-row data)。ページ (1:1752) に、親 (不明) ノードと前 (ページ (1:376)) ノードからの参照がありません。システム カタログのルート エントリが不適切である可能性があります。
メッセージ 8934、レベル 16、状態 1、行 1
テーブル エラー: オブジェクト ID 1413580074、インデックス ID 1、パーティション ID 72057594063093760、アロケーション ユニット ID 72057594068664320 (型 In-row data)。ページ (1:3645) (レベル 0) のキーの最高値が、次のページ (1:1753) の親 (0:1)、スロット 0 のキーの最低値より大きくなっています。
メッセージ 8977、レベル 16、状態 1、行 1
テーブル エラー: オブジェクト ID 1413580074、インデックス ID 1、パーティション ID 72057594063093760、アロケーション ユニット ID 72057594068664320 (型 In-row data)。ページ (1:1753) の親ノードが見つかりませんでした。
'table_xxxxxxxxx' の DBCC 結果。
オブジェクト "table_xxxxxxxxx" の 95 ページには 784 行あります。
CHECKDB により、テーブル 'table_xxxxxxxxx' (オブジェクト ID 1413580074) に 0 個のアロケーション エラーと 7 個の一貫性エラーが見つかりました。

エラー出ました。(table_xxxxxxxxの部分は実テーブル名を置き換えて表示しています)

参考サイトに従ってリペアを実施



ALTER DATABASE '対象のデータベース名' SET SINGLE_USER
GO
DBCC CHECKDB('対象のデータベース名','REPAIR_REBUILD')
GO
ALTER DATABASE "対象のデータベース名" SET MULTI_USER
GO
ALTER DATABASE "対象のデータベース名" SET RECOVERY FULL
GO


再テスト 


DBCC CHECKDB
GO


変わらず。と。

インデックスの違反なんだろうから、インデックスを再構築してしまえとも
思うんだけどもテーブル定義を見てみても、Primaryしかない
なんだかなぁ。なので、以下にチャレンジ

無理やりテーブルを再作成してみる

ざっくり言うと、別のテーブルへ移して、リネームして戻してしまえ。

1.エラーが出ているテーブル(A)をselect into で別テーブル(B)へ
2.テーブル(A)をリネーム
3.テーブル(B)をテーブル(A)へリネーム

これでパッケージソフト上でのエラーは出なくなりました。

修復できたようなので後片付け

おそらくですが、テーブル(A)のPrimaryが壊れたのだろうと推測。
→後の処置で確かに存在しえないデータが複数selectできたのでそれ。
クリアできたので、改めて以下処置を実施

ざっくり言うと、定義は生かして、今のを退避して、テーブル再構築、データ再投入

1.上記のテーブル(A)からDDLを取得
2.上記テーブル(A)をリネームし、Primaryを削除 
→これをしないとPrimaryの名称が被ったため
3.取得したDDLにてテーブルを作成
4.上記2)でリネームしておいたデータから、3)で作成したテーブルへデータを流す

作業を終えてから

DBCC CHECKDB
GO
でエラーが消えたことを確認しました

2019年2月14日木曜日

【非IT】楽天トラベル利用時の領収書 (2ヶ月以内とかじゃないよ)

これ、私も勘違いしてました。

利用後、2ヶ月過ぎたら領収書が出せなくなると思ってました。

楽天トラベルではWeb上で領収書を出力できるのですが、なぜか、過去の勘違い記憶が
残っていて、2ヶ月を過ぎたら出せなくなると思ってました。
(というか、過去の予約を検索すると「過去2ヶ月間において、国内宿泊予約はありません。」と出るので、ダメだと思ってた)

ただ、今回あれこれ調べていくうえで、2年以上前であっても出せることを確認。

結果

マイページへ移動して
「キャンセル済み・過去の予約」を選択
「過去2ヶ月間において、国内宿泊予約はありません。」と出てもくじけず、
表示期間: となっている個所を「201x年度」と変更して、「変更」ボタンを押す

これで、古い予約履歴も、「領収書印刷」ボタンも出てきます。

詳しい手順は紹介しませんが、ネットでは「2ヶ月過ぎると出せない」という記事もちらほらあったため、ご参考まで。

2019年2月6日水曜日

ssh.netで依存関係? (c# ,VS2013)

管理するサーバも増え、手作業より自動化だ!ということで、c#アプリでsshの実装をすることにしました。

過去記事にもありますが、ssh接続による作業の自動化手段として
1)TeraTerm + マクロによる実行
2)RLoginを利用した同時動作

は候補になるのですが、今後の拡張性や、各ソフトの永続性なども考慮した結果、手作りしてしまおう。と。

今回、VisualStudio2013環境で、ssh.netを利用しようとしてハマったことについて残しておきます。

まとめ (試した限り)

netSSHを利用した開発にはVisualStudio2013での開発じゃなくて、2015を使ったほうが簡単

やった手順

まずは何も考えずに進めてみる

新規でc#プロジェクトを作成、「nuget」にてssh.netのインストールを試みます。


SshNet.Security.Cryptographyの依存関係・・・

となったので、めげずに、パッケージマネージャコンソールから
PM>Install-Package SshNet.Security.Cryptography -Version 1.3.0

Install-Package : 'SshNet.Security.Cryptography' にはすでに 'System.IO' に対して定義された依存関係があります。

やっぱ同じか。。。ということでちゃんと依存関係の調査

ライブラリが足らない・・・



https://www.nuget.org/packages/SshNet.Security.Cryptography/1.3.0
NETStandardが必要なのね。ってか、このライブラリ使うの初めて。
てなことで情報収集。

フレームワークも足らない

https://dotnet.microsoft.com/download/visual-studio-sdks?utm_source=getdotnetsdk&utm_medium=referral


frameworkの4.6が必要。との事でインストール
プロジェクトへの適用が完了しました。

これでも足らないようで .net Core 1のSDKをインストール
これでも足らない・・・

VisualStudio2015で試してみよう

「2013の新規プロジェクト選択画面」

「2015の新規プロジェクト選択画面」


2015の新規プロジェクトには".net core"の選択肢がある・・・・
今回はこっちで行くことにしました

VisualStudio2015で進めてみた (結果)

PackageManagerコンソールでnetsshをインストール、問題なく進みました。
これでアプリが作れそうです

2018年12月4日火曜日

Oracle破損

※※ この情報は tipではございません ※※

とあるA社さんの仕事を委託していて、開発環境もA社さんにあるため必要に応じA社さんの環境へ接続、作業をしていたりするのですが、

??Oracle起動してないよ?
??というか、計画外シャットダウンの画面出てるよ(Windows2008server)

となり、事が深刻だったので作業備忘録メモ


前置き長くなりました。もー何で?な心境なので文体粗いです。
追伸:Oracle 10gです

【事象】


SQL DeveloperでOracleに接続しようとしたら「ORA-01033:Oracleの初期化またはシャットダウン中です」が出て接続できない

【処置概略】

・まー、今までもあったよね。startup mount;ALTER DATABASE OPEN; でつながるよね。
・おっと、mountされてるみたい。shutdown immediateしてからだね。
・え、エラー出たし。ORA- でぐぐって対処するか。
・色々コマンド出てきて打ち込むけども、なんか治らんなぁ
・余計ひどくなった。やっぱDBAでもないのにやるもんじゃないね。
・Database作り直しちゃおう。
・Configuration Assistantで再作成。っと。
・壊れたのはどうせ使えないので削除。
・ユーザー作って、権限付与して、開発用データのdmpも入れて。と。
・listener設定してなかった。作成したdbへ変更。っと。
・よしよし。データも見れるし、まぁいいか。開発環境だし。


【処置結果】

・何もtips残りませんでした。
 ひとつ大事なことは「思いたったからと言ってすぐやるな」
 OracleはさすがOracle。あちこちにリカバリログを持っていて(いるようで)、手順さえ間違わなければログから復旧できる。(はず)ログもちゃんとバックアップしておく必要あるけどね。
 適当にログ指定してリカバリしようなんて、傷を深くしただけでした。

【余談】

ファイル壊れてんじゃんか(笑) zipファイルすら破損してるよ。ディスク障害でもあったんじゃない?ま、開発環境(hyper-v)だし、壊れてもなんとかなるからいっか。

【使ったコマンドのメモ】

※sqlplus /nologでログイン
※sys as syadba

recover database until cancel;


【恥を忍んで途中からの全log】


SQL> recover database until cancel;


ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\ORADATA\ORCL\REDO03.LOG
ORA-00283: エラーによってリカバリ・セッションは取り消されました。
ORA-10562: Error occurred while applying redo to data block (file# 3, block#
21623)ORA-10564: tablespace SYSAUX
ORA-01110: データファイル3: 'D:\ORADATA\ORCL\SYSAUX01.DBF'
ORA-10560: block type '0'
ORA-00600: 内部エラー・コード、引数: [4552],[1],[0],[],[],[],[],[]
ORA-01112: メディア・リカバリが開始されていません
SQL> recover database until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:
検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
ORA-00308:
アーカイブ・ログD:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207.001をオープンできません。
ORA-27041: ファイルをオープンできません。
OSD-04002: ファイルをオープンできません
O/S-Error: (OS 2) 指定されたファイルが見つかりません。
ORA-01547: 警告: RECOVERは成功しましたがOPEN
RESETLOGSが次のエラーを受け取りました。
ORA-01194: ファイル1は一貫した状態にするためにさらにリカバリが必要です。
ORA-01110: データファイル1: 'D:\ORADATA\ORCL\SYSTEM01.DBF'
SQL> recover database until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
REDO2.LOG
ORA-00308: アーカイブ・ログREDO2.LOGをオープンできません。
ORA-27041: ファイルをオープンできません。
OSD-04002: ファイルをオープンできません
O/S-Error: (OS 2) 指定されたファイルが見つかりません。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\ORADATA\ORCL\REDO02.LOG
ORA-00310:アーカイブ・ログは順序番号2243を含んでいますが、順序番号2244が必要です。
ORA-00334: アーカイブ・ログ: 'D:\ORADATA\ORCL\REDO02.LOG'
ORA-01547: 警告: RECOVERは成功しましたがOPEN
RESETLOGSが次のエラーを受け取りました。
ORA-01194: ファイル1は一貫した状態にするためにさらにリカバリが必要です。
ORA-01110: データファイル1: 'D:\ORADATA\ORCL\SYSTEM01.DBF'
SQL> recover database automatic
ORA-00905: キーワードがありません。
SQL> recover automatic database;
ORA-00283: エラーによってリカバリ・セッションは取り消されました。
ORA-10562: Error occurred while applying redo to data block (file# 3, block#
21623)
ORA-10564: tablespace SYSAUX
ORA-01110: データファイル3: 'D:\ORADATA\ORCL\SYSAUX01.DBF'
ORA-10560: block type '0'
ORA-00600: 内部エラー・コード、引数: [4552],[1],[0],[],[],[],[],[]
SQL> recover tablespace user;
ORA-00931: 識別子がありません。
SQL> recover tablespace users;
ORA-00283: エラーによってリカバリ・セッションは取り消されました。
ORA-00368: REDOログ・ブロックでチェックサム・エラーが発生しました
ORA-00353: ブロック85960(変更217167197、時間10/01/2018
01:20:14)付近のログが破損しています
ORA-00312: オンライン・ログ3 スレッド1: 'D:\ORADATA\ORCL\REDO03.LOG'
SQL> select * from V$RECOVER_FILE;
レコードが選択されませんでした。
SQL>
SQL> recover database until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:
検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
ORA-00308:
アーカイブ・ログD:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207.001をオープンできません。
ORA-27041: ファイルをオープンできません。
OSD-04002: ファイルをオープンできません
O/S-Error: (OS 2) 指定されたファイルが見つかりません。
ORA-01547: 警告: RECOVERは成功しましたがOPEN
RESETLOGSが次のエラーを受け取りました。
ORA-01194: ファイル1は一貫した状態にするためにさらにリカバリが必要です。
ORA-01110: データファイル1: 'D:\ORADATA\ORCL\SYSTEM01.DBF'
SQL>
SQL> recover database until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\oradata\orcl\REDO1.log
ORA-00308: アーカイブ・ログD:\oradata\orcl\REDO1.logをオープンできません。
ORA-27041: ファイルをオープンできません。
OSD-04002: ファイルをオープンできません
O/S-Error: (OS 2) 指定されたファイルが見つかりません。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\oradata\orcl\REDO01.log
ORA-00310:
アーカイブ・ログは順序番号2242を含んでいますが、順序番号2244が必要です。
ORA-00334: アーカイブ・ログ: 'D:\ORADATA\ORCL\REDO01.LOG'
ORA-01547: 警告: RECOVERは成功しましたがOPEN
RESETLOGSが次のエラーを受け取りました。
ORA-01194: ファイル1は一貫した状態にするためにさらにリカバリが必要です。
ORA-01110: データファイル1: 'D:\ORADATA\ORCL\SYSTEM01.DBF'
SQL> recover database until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:
検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207
.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\oradata\orcl\REDO02.log
ORA-00310:
アーカイブ・ログは順序番号2243を含んでいますが、順序番号2244が必要です。
ORA-00334: アーカイブ・ログ: 'D:\ORADATA\ORCL\REDO02.LOG'
ORA-01547: 警告: RECOVERは成功しましたがOPEN
RESETLOGSが次のエラーを受け取りました。
ORA-01194: ファイル1は一貫した状態にするためにさらにリカバリが必要です。
ORA-01110: データファイル1: 'D:\ORADATA\ORCL\SYSTEM01.DBF'
SQL> recover database until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:
検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207
.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\oradata\orcl\REDO03.log
ORA-00283: エラーによってリカバリ・セッションは取り消されました。
ORA-10562: Error occurred while applying redo to data block (file# 3, block#
21623)
ORA-10564: tablespace SYSAUX
ORA-01110: データファイル3: 'D:\ORADATA\ORCL\SYSAUX01.DBF'
ORA-10560: block type '0'
ORA-00600: 内部エラー・コード、引数: [4552],[1],[0],[],[],[],[],[]
ORA-01112: メディア・リカバリが開始されていません
SQL> recover database using backup controlfile until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:
検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207
.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\oradata\orcl\REDO01.log
ORA-00310:
アーカイブ・ログは順序番号2242を含んでいますが、順序番号2244が必要です。
ORA-00334: アーカイブ・ログ: 'D:\ORADATA\ORCL\REDO01.LOG'
ORA-01547: 警告: RECOVERは成功しましたがOPEN
RESETLOGSが次のエラーを受け取りました。
ORA-01194: ファイル1は一貫した状態にするためにさらにリカバリが必要です。
ORA-01110: データファイル1: 'D:\ORADATA\ORCL\SYSTEM01.DBF'
SQL> recover database using backup controlfile until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:
検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207
.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\oradata\orcl\REDO02.log
ORA-00310:
アーカイブ・ログは順序番号2243を含んでいますが、順序番号2244が必要です。
ORA-00334: アーカイブ・ログ: 'D:\ORADATA\ORCL\REDO02.LOG'
ORA-01547: 警告: RECOVERは成功しましたがOPEN
RESETLOGSが次のエラーを受け取りました。
ORA-01194: ファイル1は一貫した状態にするためにさらにリカバリが必要です。
ORA-01110: データファイル1: 'D:\ORADATA\ORCL\SYSTEM01.DBF'
SQL> D:\oradata\orcl\REDO02.log
SP2-0734: "D:\oradata..."で開始するコマンドが不明です - 残りの行は無視されました
。
SQL> recover database using backup controlfile until cancel;
ORA-00279: 変更217138326(09/30/2018 12:00:48で生成)にはスレッド1が必要です
ORA-00289:
検討すべきログ・ファイル:D:\ORACLE\PRODUCT\10.2.0\DB_1\RDBMS\ARC02244_0830209207
.001
ORA-00280: 変更217138326(スレッド1)は順序番号2244に存在します。
ログの指定: {=suggested | filename | AUTO | CANCEL}
D:\oradata\orcl\REDO03.log
ORA-00283: エラーによってリカバリ・セッションは取り消されました。
ORA-10562: Error occurred while applying redo to data block (file# 3, block#
21623)
ORA-10564: tablespace SYSAUX
ORA-01110: データファイル3: 'D:\ORADATA\ORCL\SYSAUX01.DBF'
ORA-10560: block type '0'
ORA-00600: 内部エラー・コード、引数: [4552],[1],[0],[],[],[],[],[]
ORA-01112: メディア・リカバリが開始されていません
SQL> SELECT * FROM V$RECOVER_FILE;
レコードが選択されませんでした。
SQL> COL FILE# FORMAT 999
SQL> COL FILE_NAME FORMAT A36
SQL> COL TABLE_SPACE_NAME FORMAT A10
SQL> COL STATUS FORMAT A7
SQL> COL ERROR FORMAT A16
SQL> SELECT RF.FILE#, DF.NAME FILE_NAME, TS.NAME TABLE_SPACE_NAME, DF.STATUS, RF
.ERROR, RF.CHANGE#, RF.TIME
  2    FROM V$RECOVER_FILE RF, V$DATAFILE DF, V$TABLESPACE TS
  3    WHERE DF.FILE# = RF.FILE#
  4      AND TS.TS# = DF.TS#
  5  /
レコードが選択されませんでした。
SQL>
SQL>

2018年11月16日金曜日

レコード単位の計算(ireports)

なんてことない処理のはずがはまったので備忘録

要は、明細のA,B,Cの項目を合算して、Dに出したいというだけ。
手段はこれ以外あると思いますが、デザイナ環境と実行環境で動作が異なったため若干はまりました。
結果を残しておきます。

実装
KINGAKU_A,KINGAKU_B,KINGAKU_Cの計算をVariableで定義
表示フィールドにVariable名を設定


<variable class="java.lang.Double" incrementtype="Column" name="V_ROW_KINGAKU_GOUKEI" resettype="Column">
    <variableexpression>
    &lt;![CDATA[($F{KINGAKU_A}.equals(null)?0:new Double($F{KINGAKU_A}))+
    ($F{KINGAKU_B}.equals(null)?0:new Double($F{KINGAKU_B}))+
    ($F{KINGAKU_C}.equals(null) ? 0 : new Double($F{KINGAKU_C}))]]&gt;
</variableexpression>
</variable>

<textfield isblankwhennull="true" pattern="#,##0">
    <reportelement height="9" printwhengroupchanges="GroupName" width="48" x="695" y="0">
    <box leftpadding="3" rightpadding="3">
    <textelement markup="none" textalignment="Right" verticalalignment="Middle">
        <span fontname="IPA明朝">
    </span></textelement>
    <textfieldexpression class="java.lang.Double">&lt;![CDATA[$V{V_ROW_KINGAKU_GOUKEI}]]&gt;</textfieldexpression>
</box></reportelement></textfield>


2018年11月14日水曜日

Accessにてレコード超過によりデータが作成できなかった件 (未完結)

原因究明できていないため、参考までとしてください。

Accessの2GB制限と実際に投入できるデータサイズに対する実証および考察です。

ことの経緯


社内SE作業で、10,000件×10,000件の組み合わせデータを作成する必要があり、Excelではできず、Accessに頼ることにしました。

Excelにある2つのシート(各10,000件)をAccessへインポート
その後、クエリで2つのテーブルをCROSS JOINで新テーブルへINTO(1億件INSERT)

すると、謎のエラー。

accdbファイルを見ると、2GBを超えていました。Accessは2GBまでしかサポートしていないため、エラーとなったようです。

「ま~データ多いからな~」と思いつつ、今はMySQLへリンクテーブル張ってそこへ流し込んでいる段階なのですが、時間があるのでこの記事を書く事にしました。

2GBって何バイト?


改めて計算したところ、20億バイト。


これがテーブル定義なので、20Byte × 1億 件 でざっくり計算しても超えてしまいますね。

なので、母数を減らすことにしました。

10,000件 × 2,500件

これであれば、500MBに収まる試算です

でも同じエラーが出るよ???

レコードの容量計算を行うための情報収集。
ディスクのブロックサイズによって利用されるディスク領域が異なる。と。NTFSの情報を参照します。

fsutil fsinfo ntfsinfo c:

4096と出ました。つまり、4KB
今回の直接の原因にはならなそうです。

ここまでで一旦まとめ

今回の作業の目的はマトリックスデータを作って利用することであり、Accessを使ってどうこうという事ではなかったため、これ以上の深追いはしないことにしました。

考えられることとしては
1)Access内部で一時領域にディスクを利用していてそれでオーバーする
2)テーブルのインデックスなど、付加情報も容量見積に入れる必要あり
3)SELECT INTO (つまり手抜き)なので、結果作成されるテーブルのフィールド型が想定と違う? →その後データ件数を減らして実証しましたが、想定通り、元のテーブルの型を引き継いでいました

あたりが考えられますが、その詳細については今後必要に応じて調べていこうと思います