« 2010年9月 | トップページ | 2011年3月 »

2010年10月

iPhoneで最近バッテリーの消耗が激しくなった人はきっとアプリの起動しすぎです。

最近、知人の新品のiPhone4でバッテリーの消耗が激しすぎる、と言われたので
確認してみると、アプリを起動しまくっているせいだと分かりました。
[ここ]を見て、アプリを終了させましょう。
とくに、Skypeアプリが最強で、これを立ち上げっぱなしにしていると、半日でバッテリーなくなります。

複数人で同じエクセルファイルをつつくと思わぬ事故にあうので、変更されたら勝手にバックアップを作っていくようなマクロを作った。あちこちのサイトを参考にさせて頂きました。

'変数名が日本語になっているものがあるが、
'VBAの最大にして唯一の良さだと思っているので、気にしないで欲しい。(^^
'このマクロを使うと、シートを変更した瞬間に分単位で変更前の状態を
'保存するだけ(秒単位まではできる)です。
'変更前の状態というのが微妙で、Workbook_SheetChange が呼び出される直前と直後というだけです。
'Undoを使って変更前の情報を取得するところはこちらに書いてあって、面白いアイデアですね。
'ファイルの保存時には「ファイル履歴」というシートが勝手に作られて、
'そこに保存日付とファイルサイズが記録されていく。それだけのマクロです。
'バックアップファイルは、「bakcup_ファイル名」というディレクトリが勝手に
'カレントディレクトリに作られるので、その中に分単位とか秒単位で保存されて
'いくだけです。
'1時間ほどでつくったものなので、しっかり検証していません。
'自己責任で参考にしましょう。参考にならない可能性の方が大きいが。

'開いているエクセルファイルの更新時刻を取得する
Function GetUpdateTime() As String
    Dim wApplication As Application
    Dim wFileName As String
    Dim wAttribute As Integer
    Dim wReturn As String

    Set wApplication = Application
    ' ファイル名の指定

    wFileName = ActiveWorkbook.FullName
    ' ファイル属性の取得
    wAttribute = GetAttr(wFileName)

    ' 更新日時
    wReturn = FileDateTime(wFileName)

    ' 処理結果を表示
    GetUpdateTime = wReturn
End Function

'開いているエクセルファイルのサイズを取得する
Function GetFileLength() As String
    Dim wApplication As Application
    Dim wFileName As String
    Dim wAttribute As Integer
    Dim wReturn As String

    Set wApplication = Application
    ' ファイル名の指定

    wFileName = ActiveWorkbook.FullName

    ' ファイル属性の取得
    wAttribute = GetAttr(wFileName)

    ' 更新日時
    wReturn = FileLen(wFileName)

    ' 処理結果を表示
    GetFileLength = wReturn
End Function

'指定したシート名のシートが存在するかをチェックする
Function IsExistSheet(aSheetName As String) As Boolean
    Dim ws As Worksheet, flag As Boolean
    Dim wReturn As Boolean
    
    For Each ws In Worksheets
        If ws.Name = aSheetName Then flag = True
    Next ws
    If flag = True Then
        wReturn = True
    Else
        wReturn = False
    End If
    IsExistSheet = wReturn
End Function

'指定した文字列に日付と時刻を指定して一意なファイル名を生成する
'一意と言っても、分単位とか秒単位にするだけだが。
Function CreateFileName(aName As String) As String
    Dim wHizuke As String
    Dim wJikan As String
    
    wHizuke = Format(Date, "yyyymmdd")
    wJikan = Hour(Time) & Minute(Time) ' & Second(Time)
    
    CreateFileName = wHizuke & wJikan & "_" & aName
End Function

'指定したパスのディレクトリがなかったら勝手に作る
Sub CreateFolder(aPath As String)
    If Dir$(aPath, vbDirectory) = "" Then
        MkDir aPath
    End If
End Sub

Const HISTORY_FILE_NAME = "ファイル履歴"
Const BACKUP_FOLDER_NAME_PREFIX = "backup_"

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    If IsExistSheet(HISTORY_FILE_NAME) = False Then
        Application.EnableEvents = False
        
        Sheets.Add
        ActiveSheet.Name = HISTORY_FILE_NAME
        Sheets(HISTORY_FILE_NAME).Cells(1, 1) = "更新日付"
        Sheets(HISTORY_FILE_NAME).Cells(1, 2) = "ファイルサイズ(byte)"
    
        Application.EnableEvents = True
    End If

    wLastRowIndex = Sheets(HISTORY_FILE_NAME).UsedRange.Rows.Count
    Application.EnableEvents = False
    Sheets(HISTORY_FILE_NAME).Cells(wLastRowIndex + 1, 1) = "'" & GetUpdateTime
    Sheets(HISTORY_FILE_NAME).Cells(wLastRowIndex + 1, 2) = GetFileLength
    Sheets(HISTORY_FILE_NAME).Columns("A:B").AutoFit
    Application.EnableEvents = True
End Sub

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    Dim wBackupFileName As String
    Dim wBackupFolderName As String
    Dim w変更前 As Variant
    Dim w変更後 As Variant
    
    If Target.Count <> 1 Then
        Exit Sub
    Else
        w変更後 = Target
        Application.EnableEvents = False
        Application.Undo
        w変更前 = Target
        Target.Value = w変更前

        wBackupFileName = CreateFileName(ActiveWorkbook.Name)
        wBackupFolderName = ActiveWorkbook.Path & "\" & BACKUP_FOLDER_NAME_PREFIX & ActiveWorkbook.Name
        CreateFolder wBackupFolderName
        ActiveWorkbook.SaveCopyAs wBackupFolderName & "\" & wBackupFileName
        
        Target = w変更後
        Application.EnableEvents = True
    End If
End Sub

ruby-list:47543のブロックの話題。なるほど。あんまり意識したことないけど意識しないとはまりますね。

> しかし、pメソッドを実行するタイミングによって、
> [[2, 8], [6, 7], [9, 3]]
> という結果が返ってきます。
>
> このような結果になる理由がわからないのですが、
> ご教示いただけないでしょうか。

代入やメソッド呼び出しと、ブロック(特にdo~end)の結合強度の関係ですね。

ブロックを{}に変えて書きますが、それぞれ、

> *ソース
> puts "#-------------------------------------"
> p [[9,3],[2,8],[6,7]].sort do |i,j|
>   i[1] <=> j[1]
> end

p([[9,3],[2,8],[6,7]].sort){...}

> puts "#-------------------------------------"
> p a = [[9,3],[2,8],[6,7]].sort do |i,j|
>   i[1] <=> j[1]
> end
> p a

p(a = [[9,3],[2,8],[6,7]].sort){...}

> puts "#-------------------------------------"
> a = [[9,3],[2,8],[6,7]].sort do |i,j|
>   i[1] <=> j[1]
> end
> p a

a = [[9,3],[2,8],[6,7]].sort{...}
p a

と解釈されていて、上の二つではブロックなしの Array#sort の結果が p に渡
され、ブロックは無視されています。Array#sort は要素が配列だとその最初の
要素から比較するので、[[2, 8], [6, 7], [9, 3]] となっています。

ちなみに、この様な場合は sort_by を使うのがよいと思います。

>> [[9,3],[2,8],[6,7]].sort_by{|a| a[1]}
=> [[9, 3], [6, 7], [2, 8]]

Excelでマクロ使ってみてるけど、使い物にならねーので、いろいろとメソッドを追加していかねばならない。ぐはっ。

'配列のサイズをカウントする
'配列が空だった場合は-1を返す
Public Function GetSize(strAr() As String) As Integer
    On Error GoTo GetSize_ERR
    
    GetSize = UBound(strAr)
    Exit Function

GetSize_ERR:
    If Err.Number = 9 Then
        GetSize = -1
    End If
End Function

'配列の末尾にpushする
Public Sub PushBack(aArray() As String, aValue As String)
    On Error GoTo PushBack_Err
    
    Dim wMax As Integer
        
    If GetSize(aArray) = -1 Then
        wMax = 0
    Else
        wMax = UBound(aArray)
        wMax = wMax + 1
    End If
    
    ReDim Preserve aArray(wMax)
    
    aArray(wMax) = aValue
    
    Exit Sub

PushBack_Err:
    MsgBox Err.Description
End Sub

マジックトラックパッドを使い始めて2ヶ月。慣れたらこっちの方が全然いいや。相当いい。

MagicTrackPad


これを使い始めて2ヶ月くらいか。
慣れた。マウスより全然使いやすくなっちまった。
マウス特有のカチッとクリックという動作をしないで良い。
右クリックなんかもストレスなく軽いタッチで同じ動作が可能。
すげーな。アップルってところは。

evalを直接呼ぶのもかっこわるいので、Stringクラスのメンバー関数にしてみた。メンバー関数ってのはC++用語だな。

=begin
 思いつきでヘンテコな演算子を定義してみた。
 evalを利用した危険(?)な実装だ。
 StringクラスとArrayクラスに以下のような演算子を追加定義してやると
 CSVチックなデータをややこしい処理なしに配列として読み込ませることが可能。
 CSVチックなデータのセパレータが『,(カンマ)』だと『,(カンマ)』な演算子は
 定義できないので、『|』とか『/』とかを使うことになる。
 意外に便利かも。
 evalを直接呼ぶのもかっこわるいので、Stringクラスの
 メンバー関数にしてみた。メンバー関数ってのはC++用語だな。
=end

class Array
  def |(a)
    self.push(a)
    self
  end
end

class String
  def |(a)
    [self,a]
  end
  def csv2array
    wRet=eval(self)
    wRet
  end
end


if __FILE__==$0
  require "kconv"


  #CSVのようにセパレートされた文字を配列にする
  puts %Q("Umetaro|Saitani"|"1000"|"2010|0930"|"05:00:01"|"23:00:12").csv2array

  DATA.read.each do |i|
    puts "------------------------"
    wRet=i.csv2array
    wRet.each_with_index do |j, index|
      puts %Q(#{index}:#{j.tosjis})
    end
  end
end

=begin 出力結果
Umetaro|Saitani
1000
2010|0930
05:00:01
23:00:12
------------------------
0:氏    名
1:社員番号
2:日付
3:出勤時間
4:退勤時間
------------------------
0:坂本龍馬
1:1000
2:2010/09/30
3:05:00:01
4:23:00:12
------------------------
0:木戸孝允
1:1001
2:2010/09/30
3:04:12:31
4:23:10:10
------------------------
0:西郷隆盛
1:1002
2:2010/09/30
3:06:00:00
4:21:12:31
------------------------
0:ドラえもん
1:1003
2:2010/09/30
3:08:01:00
4:17:00:01
=end

__END__
"氏    名"  | "社員番号" | "日付"       | "出勤時間" | "退勤時間"
"坂本龍馬"  | "1000"     | "2010/09/30" | "05:00:01" | "23:00:12"
"木戸孝允"  | "1001"     | "2010/09/30" | "04:12:31" | "23:10:10"
"西郷隆盛"  | "1002"     | "2010/09/30" | "06:00:00" | "21:12:31"
"ドラえもん"| "1003"     | "2010/09/30" | "08:01:00" | "17:00:01"

« 2010年9月 | トップページ | 2011年3月 »

2013年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

最近の記事

最近のコメント

最近のトラックバック

無料ブログはココログ