プログラミンGOO

プログラミングナレッジ、ワードプレス、広告収入等について、気づき・備忘録を残していきます。

VBA備忘録

【セル・行の操作】

■コピーペースト コピペ
★PasteSpecialのオプションであるxlPasteAllは処理速度が非常に遅い。値のみであればxlPasteValuesを使用する。
セルをコピーペースト

Range("A1:B2").Copy
Range("A3").PasteSpecial  'PasteSpecialは書式を保持する

※値の貼り付けの場合
Range("A3") = Range("A1:B2")

Sub copyPaste(fromWs, fromRow, fromCol, roWs, toRow, toCol)

  fromWs.Ceells(fromRow, fromCol).copyPaste
  toWs.Cells(toRow, toCol).PasteSpecial
End Sub

・行をコピーペースト

ws.Rows(2).Copy '2行目をコピー
Rows(3).PasteSpecial(xlPasteAll)  '3行目に貼り付け 書式アリ

■Cells、Rangeの変換、書き換え
Range→Cells

Cells(ws.Range("A1").Row, ws.Range("A1").Column)

Cells→Range

Cells(1, 1).Address  '"$A$1"
Cells(1, 1).Address(False, False)  '"A1"

■行を挿入

ws.Rows(2).Insert  '2行目に行を挿入

■最終列を取得
※空白もスキップして最終を取得する場合
Excel自体の最終列からCtrl+←で最終列を取得する

ws.Cells(y, Columns.Count).End(xlToLeft).Column  '最終列
ws.Cells(Rows.Count, x).End(xlUp).Row  '最終行

※空白までを取得する場合
特定のセルからCtrl+→で最終列を取得する

ws.Cells(y, x).End(xlToRight).Column  '最終列
ws.Cells(y, x).End(xlDown).Row  '最終行

■セルの検索

Dim r As range
Set r = ActiveSheet.range("B:B").Find(What:="出力先フォルダを選択:")

・特定文字列を持つセル

Cells.Find("str")

■セルの結合

Range("A1:B2").Merge

・セルから結合エリアを取得

Dim mergeRange As Range
mergeRange = Cells(1,1).MergeArea
  'セルA1がいずれかのセルと結合されていた場合に範囲をRangeオブジェクトで返す

・結合エリアの行数

mergeRange.Rows.Count

■特定行以下のセルをすべて消去・削除

'削除
Sub DeleteRowsBelow()
  Worksheets("Sheet1").Rows(5 & ":" & Worksheets("Sheet1").Rows.Count).Delete
End Sub

■重複削除

shError.Range("A:A").CurrentRegion.RemoveDuplicates Columns:=1, Header:=xlYes

※1行目にヘッダーが存在しないばあはHeader:=xlNo
※1行しかない場合エラーになる可能性

■オートフィル

With Range("A1")
  .Value = "1月"
  AutoFill Destination:=Range("A1:A12")
End With

★行数をコントロールするためにデフォルトを1行のみにすると関数やグラフに不具合が出ることがある。
2行残すとエラーが起こりづらい。

■フィルターの設定

Range("A1:C6").AutoFilter 1, "*.png"  '末尾が『.png』で終わるもの

※これはExcel自体のフィルター機能を利用している。
その性質上複数条件を設定するのは向いていない。

・解除

Range("A1:C6").AutoFilter  '引数なしで使うと解除

■演算子

And
Or
Not

=
<>
<=, >=

■型判定、型チェック

VarType(val)

結果は~型、ではなく数値で返される。対応は以下の通り

Integer	2
Double	5
String	8
Boolean	11
Date	7
Object	9
Variant	0

■型変換
文字列変換

CStr(val)

同じように日付に変換したいならCDate(val)のように各種対応している

■日付の取得
Date で年月日
Now で日時
・フォーマットの設定

format(Date, "yyyy年mm月")

■日付の差分をとる

DateDiff("d", startDate, endDate)

※"d"で日単位の差分をとる
※差分のため、1/1~1/2を指定すると戻り値は2ではなく1となることに注意

【シート・ワークブック操作】

■ブックを選択

Dim wb As Workbook
Set wb = ActiveWorkbook

■指定のExcelのパスを調べる

ThisWorkbook.Path

■カレントディレクトリを調べる

CurDir

■シートの作成

Worksheets.Add After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = "田中"

■シートのコピー

Worksheets("Sheet2").Copy After:=AcriveWorkbooks("Book2").Worksheets("Sheet1")

■シートを選択
・シート名で選択

Dim sh As WorkSheet
Set sh = wb.Sheets("sheetName")

・インデックスで選択

Dim sh As WorkSheet
Set sh = wb.Sheets(1)

■シートのデータを消去・削除

sheet.cells.clear  '消去
sheet.cells.delete  '削除

【ファイル操作】

■Excelブックを開く
・ダイアログを開いてファイルを選択させる

Dim openFile As String
openFile = Application.GetOpenFilename("Microsoft Excelブック,*.xls?")
If OpenFile <> "False" Then
    Workbooks.Open OpenFile
Else
    MsgBox "キャンセル"
End If

■複数のExcel選択を許可する場合

Dim openFiles As String
openFiles = Application.GetOpenFilename("Microsoft Excelブック,*.xls?", MultiSelect:=True)
'キャンセル選択時
If VarType(openFiles) = 11 Then
  If OpenFiles = False Then
    MsgBox "キャンセル"
    Exit Sub
  End If
End If

'全ファイルループ
For i = To UBound(openFiles)

  Debug.Print(filePaths(i))
End If

・指定のパスのエクセルを開く

Dim wb as Workbook
Dim filepath as String  'ファイルパス
Set wb = Workvooks.Open(Filename:=filepath)

・複数 ダイアログを開きフォルダを選択させる>フォルダ内の複数ファイル処理

With Application.FileDialog(msoFilleDialogFolderPicker)
  If .Show = True Then
    folderPath = .SelectedItems(1)
  'キャンセル選択時
  Else
    Exit Sub
  End If
End With

'全ファイルループ ~FileSystemObjectを使用する場合~
Dim files As Object
Set filse = CreateObject("Scripting.FileSystemObject").GetFolder(folderPath).files

For Each file in files
  '処理
  Debug.Print(folderPath + file.Name)
Next file

'全ファイルループ ~Dir関数を使用する場合~
'Dir関数:該当するパスが存在する限りファイル名を返し続ける
Dim filePath, fileName As String
fileName = Dir(folderPath + "/*")

Do While fileName <> "" 'ファイル名が出てこなくなるまでループ
    '処理
    filePath = folderPath + "/" + fileName
    Debug.Print(filePath)
    fileName = Dir()  '引数なしでDir関数を実行すると次のパスに切り替わる
Loop

※Dir関数はネストできないというデメリットがある。
一方で、FileSystemObjectは型がオブジェクトになるため少し癖がある。

■パスワードがかかっていたら解除
VBAでは、ファイルを開くタイミングでパスワードがかかっているかを判定することができない。
※すでに開いてあるbookがパスワード付きであるかは判別できるが、これでは意味がない。

そのため、以下の方法が考えられる。
1. 先にパスワードを設定して開く ※パスワードがかかっていないExcelにこの処理を施してもエラーにはならない
2. まず読み込んだExcelのうち、どのExcelがパスワード付きかを一通り判別(Open時エラーになるかで判別)し、あらためて解除を行う。

2では2重処理となるので1の方法を取る。

■ファイルの保存

・上書き保存

wb.Save

・名前をつけて保存

book.SaveAs Filename:="C:/~~~/sample.xls"

・警告メッセージの停止
『変更内容を保存しますか?』などを表示させない

Application.DisplayAlerts = False '警告文停止
wb.Save
wb.Close
Application.DisplayAlerts = True  '警告文再開

※拡張子を表示しない設定になっているときはWorkbooks("Book1").Save としないといけない。
極力別の方法でWorkbookを事前に設定しておく。
以下のようにオプションで指定する方法もあるよう

wb.Close SaveChanges:=True  '保存して閉じる
wb.Close SaveChanges:=False  '保存しないで閉じる

■ThisWorkbook以外を閉じる

Sub closeWb()
  Dim bk As Workbook
  For Each bk In Workbooks
    If Not (bk Is ThisWorkbook) Then
      bk.Close SaveChanges:=False
    End If
  Next
End Sub

■ファイルパスからファイル名を取得

Function getFileName(filePath)
  getFileName = Dir(filePath)
End Function

■ファイルパスをセット

Public Sub setFilePath(toRow, toCol)

  Dim filePath As Variant
  filePath = Application.GetOpenFilename(FileFilter:="Microsoft Excelブック,*.xls?", MultiSelect:=False)

  'キャンセル選択時
  If filePath = False Then
    Exit Sub
  End If

  Cells(toRow, toCol) = filePaths
EndSub

■フォルダパスをセット

Public Sub setFolderPath(toRow, toCol)
  With Application.FileDialog(msoFileDialogFolderPicker)
    .AllowMultiSelect = False

    'キャンセル選択時
    If .Show = 0 Then
      Exit Sub
    Else
      Clees(toRow, toCol) = SelectedItems(1)
    End If
  End With
End Sub

■フォルダ内のすべてのExcelに処理を行う

resourceFolderPath = shView.Range(CELL_RESOURCE_FOLDERPATH)
fileName = Dir(resourceFolderPath + "\*.xls?")

Do While fileName <> ""
  Workvooks.Open resourceFolderPath + "\" + fileName
  AcriveWorkbook.Close
  fileName = Dir()  '引数なしでDir関数を実行すると次の値に処理が移行する
Loop

【関数】

■For文

For i = 1 To 3
    ' 処理
Next i

■for文を抜ける

Exit For

■For Each
For Each I In arr
'処理
Next

■配列のUBoundがあるかどうか
配列の長さを取得するUBoundは、配列に値が存在しない場合、エラーになる。
そのため、事前に配列が初期化されているかチェックを行う必要がある。

'配列が初期化前であるか判定する
Function isEmptyArray(s() As String) As Boolean
  If (Not s) = -1 Then
    isEmptyArray = True
  Else
    isEmptyArray = (UBound(s) = 0 And s(0) = "")
  End If
End Function

■処理をすべて修了

End
関数のみを修了
exit function
exit sub

■文字列操作
・分割

Split(元の文字列 , 区切り文字)

【例外処理】

■基本的な仕様

On Error GoTo Label 'エラー検知をONにする。これ以降、もしエラーが発生したらLabelにジャンプ
~method~  'エラーが起きるかもしれない処理
On Error GoTo 0 'エラー検知をOFFにする

Label:  'エラーが起きたら強制的にこの位置にジャンプ
  ~method~  'エラーが発生した場合の処理
  Resume NextStep '次にNextStepへジャンプ。Resumeするとエラーは空になる

※問題点として、エラーが起きなかった場合もLabel無いの処理は実行される。これをどのように回避するか

■基本実装
・エラー処理を完全に分離する。

~通常処理~
Exit Sub

ErrorLabel
  ~method~  'エラーが発生した場合の処理

End Sub

※※※悪い例
ErrorLabel:
If Err.Number <> 0 Then
  ~method~  'エラーが発生した場合の処理
  Resume ErrorNext
End If

'Err.Numberの有無で処理するか否かを判定する方法がネットでは良く見つかる。
しかしこれでは意図したものとは異なる部分でエラーが走った場合にもこの部分の処理が走ってしまう。

そのため上記の実装となるが、これでもまだ課題がある。
開いていたファイルを閉じたいなど、通常時・エラー時ともに最後に行いたい共通処理がある場合に実装できない。
その場合は以下のようにする。

■推奨の実装

~通常処理~
On Error GoTo Label
~method~  'エラーが起きるかもしれない処理
On Error GoTo 0

~通常処理~

GoTo Finally  ’Finallyに飛ぶため、以下の処理は通常時は実行されない

'エラー時のメソッドを記述するスペース............................................................

ErrorLabel:
  ~method~  'エラーが発生した場合の処理
  Resume ErrorNext

'エラー時のメソッドを記述するスペースここまで............................................................

Finally
~エラー時、通常時ともに実行したい場合の処理~

End Sub

【グラフ】

■グラフ名を調べる
・方法1
グラフを選択>Excel左上のプルダウンにグラフ名が表示される
・方法2
検索と選択>オブジェクトの選択と表示

■グラフにアクセス

Dim chartObj As ChartObject
Set chartObj = stDAILY.ChartObjects(1)

■グラフの系列にアクセス
参考:
Office TANAKA - Excel VBA Tips[グラフの参照範囲を変更する]

・系列はSeriesCollectionというオブジェクトで格納されている
Formula関数を使うとSeriesCollectionの値を取得できる

=SERIES(シート名!ヘッダーセル, シート名!縦軸データ範囲, シート名!横軸データ範囲, プロット順)

※プロット順とはグラフにデータが描画される順番

・以下で試しに表示できる

Dim msg As String, i As long
With ActiveSheet.ChartObjects(1).Chart
  For i = 1 To .SeriesCollection.Count
    msg = msg & .SeriesCollection(i).Formula & vbCrLf
  Next i
End With
MsgBox msg

【画像の比較】

バイナリファイルに変換して比較する
参考:
VBAで2つの画像ファイルを比較して内容が同一かどうかを判定する方法 - t-hom’s diary

~バイナリファイルを返す関数~
※ファイル名は違うが画像自体は同じ『bbb.png』と『ccc.png』がある場合

Dim pass1, pass2 As string
pass1 = "C/aaa/bbb.png"
pass2 = "C/bbb/bbb.png"

Debug.Print(ReadBmpAsString(pass1) = ReadBmpAsString(pass2))  'True

Function ReadBmpAsString(file_name As String) As String
  Dim bmp() As Bute
  Open file_name For Binary As #1
    ReDim bmp(LOF(1))
    Get #1, , bmp
  Close #1
  ReadBmpAsString = bmp
End Function

【モジュール】

関数単位からエクスポートが可能
■エクスポート
モジュールをみぎっクリック>ファイルをエクスポート
標準モジュール: .bas形式で保存される
クラスモジュール: .cls形式で保存される

■インポート
ファイル>ファイルのインポート

■クラスモジュールの使用
・main関数の宣言ブロックでクラスをインスタンス化して使用する

Private ins As New moduleName
Sub main()
  ins.method
End Sub

・モジュール内でインスタンス化して使用する

Sub main()
  Dim ins As Class1
  Set ins = New Class1

  ins.method
End Sub

・引数を渡す

  ins.method arg1, arg2  'カッコなどでくくらず、半角スペースの後に引数を記載する

【appendics】

■処理高速化
実際にファイルを開く挙動などをUIに反映させずに行う設定をすることで処理を高速化する

'高速化開始
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

'高速化終了
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic

■背景色色付け

Range("B2").Interior.ColorIndex = 3     ''色パレットの3番を設定します 黄色:6、赤:3
Range("B3").Interior.Color = RGB(0, 0, 255)  ''青色に設定します

背景色ではなく文字に色付けしたい場合はInteriorではなくFontを指定する

■ソート
※配列をソートするのではなくExcel自体の機能であるソートを起動する

With ws.Sort
  .SortFields.Clear 'ソートをリセット
  .SortFields.Add Key:=Cells(y, x) 'キー(ヘッダー)となるセルを指定
  .SetRange Range("A1:B3")
  .HEADER = xlYes 'ヘッダー行が無い場合はxlNo'
  .Apply
End With

■スクロールトップ
処理終了時に最初のワークシートの一番上に表示を合わせておきたい場合など

ws.Activate  '対象のワークシートをアクティブにする
ws.Cells(1, 1).Select  'ついでにセルA1を選択
ActiveWindow.ScrollRow = 1

■カラムセット

'ヘッダー行に特定の文字列が見つかったらその列番号を返す。無ければ0
Function searchCol(ws, headerRow, colName, colEnd)

For i = 1 To colEnd
  If Rplace(ws.Cells(headerRow, i), vbLf, "") = colName Then
    searchCol = i
    Exit Function
  End If
Next i

searchCol = 0

End Function

■マクロ実行時に引数を渡す
図形などにマクロの登録をする際、マクロに引数を渡したい場合がある。
引数を渡すにはマクロ登録で以下のように関数名、引数を半角スペースをあけて私、マクロの個所をシングルクォーテーションで囲う

const HIKISU = "hikisu" がモジュール内で定義してある場合
●●.xlsm!'sheetReset HIKISU'

そのまま文字列を渡す場合
●●.xlsm!'sheetReset "hikisu"'

どちらでも可

複数渡す場合

●●.xlsm!'sheetReset "hikisuA", "hikisuB"'

■オブジェクト名の変更
各シートにはオブジェクト名が設定されており、その名前で呼び出せる。
このオブジェクト名を変更するにはVBProjectという本体のオブジェクトにアクセスしなければならない。

初期設定ではVBProject自体へのアクセスが禁止されているのでまずはExcelの設定から。
ファイル>その他>オプション>トラストセンター>トラストセンターの設定
VBAプロジェクトオブジェクトモデルへのアクセスを信頼する:True

・実装

Sheets.Add after:=sheets("Sheet1")  'シート追加
ActiveWorkbook.VBProject.VBComponents(ActiveSheet.CodeName).Name = "stForWork"

■他のExcelにあるVBAを実行する
・同じ改装にあるExcelのVBAを起動

Application.Run("sample.xlsm!main")

・パス指定する場合は、パスの部分をシングルクォーテーションで囲う

Application.Run("'C:\パス\sample.xlsm'!main")

・変数で指定(相対パス)

Dim path As String
path = ThisWorkbook.path
Application.Run("'" + path + "'" + "!main")

■空白セルを詰める
>重複削除で実現できる

■vbaでしか可視化できないシートを作る
プロパティウィンドウ>Visible>Veryhidden

■メッセージボックスに値を入力させたい
formで作れる

■勝手に折り返しになるのを防ぐ
改行とかが入ると勝手に折り返し表示になる。

shError.Range("A:A").WrapText = False

■ValueとText
Valueはデフォルト。つまり以下は同じ。

Debug.Print(ws.Range("A1"))
Debug.Print(ws.Range("A1").Value)

一方、Textは書式を適用して値を取得する。
A1セルのValueが2021/18/1で、書式で2021年1月1日と表記されている場合は以下になる。

Debug.Print(ws.Range("A1").Value)  '2021/1/1
Debug.Print(ws.Range("A1").Text)  '2021年1月1日

Textはif文などでエラーの温床となるためできるだけ使用しない。

■改行コード
VBAの改行コードはVbLf…のはず

■空白・改行コード削除

Function replaceSpaceBreak(val)
  val = Replace(val, vbLf, "")
  val = Replace(val, vbCr, "")
  val = Replace(val, vbCrLf, "")
  val = Replace(val, " ", "")
  val = Replace(val, " ", "")
  replaceSpaceBreak = val
End Function

■命名規則
変数:ロワーキャメルケース(sampleVal)
グローバル変数:アッパーキャメルケース(SampleVal)
仮引数:スネークケース ※すべて小文字(sample_val)
定数:スネークケース ※すべて大文字(SAMPLE_VAL)
関数・クラス名:アッパーキャメルケース(SampleVal)

■複数の変数の同時宣言はしないこと!
参考:Excel VBAコーディング ガイドライン案 - Qiita

Dim a, b As String

bはString型になるが、aはVariant型になってしまう!

■参照渡しと値渡し
参考:Excel VBAコーディング ガイドライン案 - Qiita

Dim arg As Long
SampleSub arg '参照渡しになる
SampleSub(arg) '値渡しになる
Call SampleSub(arg) '参照渡しになる
SampleSub((arg)) '値渡しになる
Sub SampleSub(ByRef arg) '参照渡しになる
SampleSub(ByVal arg) '値渡しになる

■データバー
Excel VBA データバーを表示する条件付き書式設定する
ただ、これだけだと最小値のときにデータバーの長さが0となる。※最小値が0でなくても
本来はデータの値が0のときにデータバーの長さを0としたい。

>対処法

With ws
  Set dataBar = .Range(.Cells(rowStart< i), .Cells(rowEnd, i))
End with
dataBar.FormatConditions(1).MinPoint.Modify newtype:=xlConditionValueAutomaticMin

参考:
【VBA】データバー表示と削除、コピー元範囲指定を解除する | 自恃ろぐ-jizilog.com-

■VBAテストツール
RubberDuck アドインとして導入できる
参考:
・機能について
VBA開発環境をモダンにする - RubberduckとVBEThemeColorEditorの紹介 - Qiita
・テスト実装
vbaにはユニットテストや - Google 検索

VB Lite Unitもよさそう

【エラー対応ログ】

■Range(Cells(y, x), Cells(y, x) ができない
Cellsにもワークシートを指定する必要がある

■if文の中でEnd FunctionするとEnd Ifがありませんエラー
Endではなく Exit Function

■Range().clearで結合セルだとエラー
clearではなくRange().vallue="" とする

■If n = Null が機能しない

If IsNull(var) Then

というか空白セルの判定の場合は

If IsEmpty(var) then

■Selectしようとしたらエラー
対象のworksheetがアクティブになっていないとエラーになる

ws.activate  'アクティブにする
ws.Cells(1, 1).Select

■SubまたはFunctionの属性が適切ではありません
属性とはPrivateとかPublicとかのこと。これの付け方が間違っている。
例えばPrivate属性はプロシージャ内では指定ができずエラーになる。

Sub sample()
  Private a as Variant  'エラー
End Sub

■Typeブロック外では無効なステートメントです
ステートメントとは宣言のこと。宣言が変だよと言われている。
・エラー

Sub main()
  ins As New Class1  'エラー
End Sub

・正しくは

Sub main()
  Dim ins As Cass1
  Set ins = New Class1
End Sub

【検索ワード】

★vba 開始日 終了日 日数
安全ではない可能性のある外部ソースへのリンク
セルから日付を取得する方法
オブジェクト名 設定
vba エスケープが必要な文字:『"』だけ?
★重複削除 1行のみ エラー
★Range.Sort

【仕上げ】

マクロにパスワードをかける
高速化
関数名に説明が記載されている
印刷設定
グリッド線を消す
表示:改ページプレビュー
フォントサイズ:タイトル>見出し1>見出し2のように整合性をもたせる
倍率:100%にする

【VBAのイけてないところ】

・配列でutilメソッドが少なすぎる。値が配列に存在するか否かすら判定できない
・『/』あり形式のDateをformatでyyyymmとか指定すると日付がバグる
・RangeとCellsの変換が手間すぎる

Vue.js&Typescript備忘録

【Vue起動】

cdコマンドでVueプロジェクトに移動

npm run serve

■バージョン確認
・Node.js

node -v

・npm

npm -v

・Vue

npm list vue  //プロジェクトにインストールしている場合
npm list -g vue  //グローバルにインストールしている場合

・VueCLI

vue -V

・2021/10時点での最新の安定バージョン
Vue: 2.6.14
Vue/cli: 4.5.13

・TypeScript

tsc -v

【Vue.jsの特徴】

  • 双方向バインディングでリアルタイムに値の更新が可能
  • コンポーネントで部品化し、複数のコンポーネントを組み合わせることで柔軟にviewを生成する
  • SPAを作るのに適している
  • 単一ファイルコンポーネントで作成する(HTML、js、cssを1つのファイルに記述する)

【Vueプロジェクトの基本】

  • viewフォルダにはテンプレートを、componentsフォルダには再利用可能なコンポーネントを作成する
  • App.vueでアプリケーションを定義し、そこからviewのHome.vueを呼び出す。
  • Home.vueからcomponentsフォルダのコンポーネントを呼び出して使用する。

App.vue(ルート)
┗Home.vue(viewフォルダ)
 ┗Comp.vue(componentsフォルダ)
たとえば、Header.vueならApp自体の構成になるのでApp.vue直下に置く。
App.vueのでrouterフォルダの設定ファイルの記載に基づいてパスがルーティングされる
デフォルトでは『/』をHomeと読みかえる記述となっているため、viewフォルダのHome.vueが読み込まれる。

  • CSSは遷移元のCSSを引き継ぐため、複数のビューで同じCSSクラス名を使用していると意図しない装飾が反映される。命名規則などによる明確な定義が必要

~App.vue~

<temeplate>
  <div>  //vueでは1コンポーネントしかk返さない約束なので、template内は1つのdiv等にまとめる
    <Questions></Questions>  //@Componentしたファイルを要素として呼び出せる
  </div>
</template>

<script lang="ts">
  import { Component, Vue } from 'vue-property-decorator'  //使用するアノテーションを定義
  import Question from './components/question.vue'  //コンポーネントとして使用するファイルをimportして名前を付ける

  @Component({
    components: {
      Questions  //importしたファイルをHTMLの要素として登録
    }
  })
  export default class App extends Vue {
    //設定したjsを記載する
  }
</script>

【v-bindとv-on】

<input
  type="text"
  :value = "clientNameChild"
    //:valueはv-bind:valueの省略形
    //子にデータを渡す場合に記述する。自身のコンポーネントのみで使用する場合は不要
    //inputのvalue(入力された値)を子コンポーネントのclientNameChildプロパティに代入
  @input = "clientName = $event.target.value"
    //@input=v-on:inputと同義
    //inputを監視して自身のclientNameプロパティを更新する
>

【v-model】

v-modelはv-bindとv-onをまとめたもの。
フォームアイテムによってv-bindとv-onの展開のされ方は異なる

アイテム: v-bind/v-on
テキストボックス、テキストエリア: value/input
チェックボックス、ラジオボタン: checked/change
セレクトボックス: value/change

【v-for】

参考:
【徹底解説】これを見ればわかるvue.jsのv-forのkeyの動作 | アールエフェクト

<div v-for="category in categories" v-bind:key="category.id">
  <Category
    :category = "category.text"  //:categoryはv-bind:category の省略形
    :category1Desc = "category.desc"
  />
</div>

※文字列と組み合わせたい場合には以下

<Category
  :category1 = "'addText' + category.title"  //固定テキストは『'』でくくる
/>

v-bindは、指定した要素が何らかのリクエストを起こした際にレスポンスをどの要素に返すかを示す。
なのでv-forで複数の要素が生成される際や、inputで値を入力した際に使用される。

・ラジオボタンのバインディング
参考:
Vue.jsでラジオボタン [radio button]

~Question.vue~ ※子コンポーネント

<div v-for="item in selection" v-bind:key="item.index">
  <input type="radio"
    :name="'question' + id"
    :id="'question' + id + '-item' + item.point"
    v-bind:value="item.point"
      //radioのvalueを設定
      //省略して:value="item.point"のみでも可
    v-on:change="$emit('changed', $event.target.value)"  …①
      //radioなのでeventは"change"を指定する。
      //"$emit('関数名', 関数の引数)" 親要素ではこの関数名で呼び出せる
      //$eventはv-on:changeイベント自身を指す
      //すなわち、radioボタンが変更(change)されたらその値(target.vlue9を引数に関数が発火する
  >
  <label :form="'question' + id + '-item' + item.point"> {{ item.text }} </label>
</div>

~Home.vue~

<template>
  <Question
    @changed="fire"  //①で指定した関数名を感知して"fire"メソッドを発火。引数も同時に受け取っている
    :id="question.id"
    :selection = "question.selection"
  />
</template>

<script>
fire (val) {  //引数、すなわちradioで選択された値を受け取ることができる
  console.log(val)
}

selection = [
  {
    text='質問1'
    poitn=1
  },
  {
    text='質問2'
    poitn=2
  }
]

【propsと@Prop】

Vueでは親コンポーネントで子コンポーネントを呼び出す際に、一緒にプロパティを渡すことができる。
子コンポーネントでは、そのプロパティを受け取るためにpropsを使用する。

~親コンポーネント~

<SampleComp
  :sampleProp="sample"
/>

~子コンポーネントでの値の受け取り~
・通常の書き方 ※props

<script>
export default {
  props: {
    userName: {
      type: String,
      required: true
    }
  }
}
</script>

・typescriptの書き方 ※@Prop

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Componrnt
export default class SampleComponrnt extends Vue {
  @Prop({ type: String, required: true })
  userName: string;
</script>

■配列をpropsとして渡す

items: ['iphone', android]

<template>
  <div v-for="item in items" v-bind:key="item.index">
    //配列がidを持っていれば:key="item.id"が理想
    <p>{{ item }}</p>
  </div>
</template>

<script lang="ts">
  @Prop
  items!: [];  //Array<String>;といった渡し方の方が正解?
</script>

※divでなくspanで渡す場合はindexof()?

<span v-for="item in items" v-bind:key="item.indexof()"></span>

【Emit】

参考:
propsと$emitでデータを引き渡す - Qiita

■基本
~Child.vue~

<template>
  <div></div>
</template>

<script lang="ts">
export default class Category extends Vue {
  sumChild = 0;

  function () {
    this.sumChild += 1;
    this.$emit('eventName', this.sumChild);  …①
      //this.$emit('親に送信するイベント名', 値)
  }
}
</script>

~Parent.vue~

<template>
  <Child
    @eventName="sumParent=$event"
      //@eventNameで①で指定したイベント名を感知
      //$eventに子から送信された値が入る
  />
</template>

<script lang="ts">
export default class Category extends Vue {
  sumParent = 0;
}
</script>

・直接ではなく関数に値を送信したい場合
~Parent.vue~

<template>
  <Child
    @eventName="reflentSum"
  />
</template>

<script lang="ts">
export default class Category extends Vue {

  reflectSum (e) {  //eに子から送信された値が入る
    console.log(e);
  }
}
</script>

・inputのvalueではなく別の値を介したい場合は関数を挟む
~Child.vue~

<input type="●●"
  v-bind:value="value"
  v-on:change="changed"
>
<script lang="ts">
export default class Sample extends Vue {
  changed (e) { //イベントを任意の引数名でキャッチできる ※今回はeと指定している個所
    let newItem = 0;
    newItem = e.target.value + 1; //何らかの処理
    this.$emit('changedNext', newItem)  //('関数名', '関数の引数') 親要素ではこの関数名で呼び出し引数を受け取る
  }
}
</script>

・watchも使いやすい?
[vue.js]子コンポーネントの値を親コンポーネントで合計したい


■フォームから
子コンポーネントで親に値を送信
~Child.vue~

<input type="●●"
  v-bind:value="value"
    //inputのvalueを設定
    //省略して:value="value"のみでも可
  v-on:change="$emit('changed', $event.target.value)"  …①
    //v-on:イベント名。radioならchange、buttonならclick
    //"$emit('関数名', 関数の引数)" 親要素ではこの関数名で呼び出せる
    //$eventはv-on:changeイベント自身を指す
    //すなわち、radioのボタンが変更(change)されたらその値(target.value)を引数に関数が発火する
>

親コンポーネントで受け取り
~Parent.vue~

<template>
  <Child
    @change="fire"  …①で指定した関数を感知してfireメソッドを発火。①の引数がfireメソッドの引数となる
  />
</template>

<script lang="ts">
export default class Category extends Vue {

  fire (val) {
    console.log(val);
  }
}
</script>

・直接値を渡したいなら
参考:
Vueのデータバインドの基本 - Qiita

~Parent.vue~

<template>
  <Child
    @changed="propName=$event"  //子コンポーネントから送られた引数が#eventとしてわたってくる
  />
</template>

・さらに親となるコンポーネントに値を伝はさせたい
方法1 :Watchで変更を監視

@Watch('propName', { deep: true })  //propName子要素の変更まで感知する場合はdeep: true
propNameChangedDeep () {
  console.log('catch'
}

【算出プロパティ】 computed

template内での扱いは通常のプロパティと同様。
プロパティとして使用したいが、複数の値や条件、式から値が算出される場合に使用する

<template>
  <p>{{ fullName }}</p>
  <p>{{ sendMessage }}</p>
</template>

<script lang="ts">
@Prop
parentMsg!: string;

export default class Home extends Vue {
  firstName: string = '太郎';
  lastName: string = '山田';

  get fullName() {  //typescriptの場合はget funcName() { とするだけ
    return `${this.firstName} ${this.parentMsg + 'です'
  }
}
</script>

■ゲッターとセッター:getter,setter

private get propName (); <戻り値の型> {
  return <戻り値>
}

private set propName (): void {
  ~更新処理~
}

【画面遷移】viewの切り替え

※パスによるコンポーネントの切り替えであり、URLは変わらない
■参考:
Vue.jsでフォームを使おう - Qiita


■基本
~Home.vue~

<template>
  <button @click.prevent="validate">回答する</button>
</template>
<script lang="ts">
  ~~~
  validate () {
    this.$router.push(' /result')  //<router-link :to="…">と同義
  }
</script>

~router/index.ts~

  {
    path: '/result',
    name: 'Result',
    component: () => import('../views/Result.vue')
    props: true  //★値を受け渡す場合はこの記述が必要
  }

~Result.vue~
■viewを切り替える際の値の受け渡し
上記基本の下、routerの設定でpropsをtrueにしてある前提

以下のようにparamsで指定する。
★パラメータはStringにしないとエラーになる

validate () {
  this.$router.push({
    name: 'Result',
    params: {
      param: String(this.param)  //自身のparamを遷移再起のparamに渡す
    }
  })
}

【バリデーションフィルター】

■参考:
Vue.JSでフォームのvalidationを行う - Qiita
フィルター — Vue.js
単純なフォームバリデーション
フォームのバリデーション — Vue.js


■filtersを使う方法 ※要検証だし@Componentに書かないといけない?

@Component({
  filters:
    validator (clientNmae: string) {
      if (!clientName) return ''
      return clientName.charAt(0).toUpperCase() + clientName.slice(1)
    }
})

■VeeValidateライブラリを使用するのがよさそう
Vue.js のフォームバリデーションライブラリ VeeValidate を評価してみた | DevelopersIO
デモあり
VeeValidateでVue.js用の超便利なバリデーションを実装する | カバの樹
【Vue.js】VeeValidateがメジャーバージョンアップで便利になっていた – 株式会社シーポイントラボ | 浜松のシステム・RTK-GNSS開発
古いバージョンとの差異
VeeValidate 2から3へのアップデート - 一休.com Developers Blog

・導入

npm install vee-validate --save

バージョン確認
node_modules/veevalidate/README.meを参照

・import

import { extend, ValidationProvider, ValidationObserver } from 'vee-validate'
import { required, email } from 'vee-validate/dist/rules'
extend('required', required)  //template内でrequiredの名前で使用できるようにする

@Componentに以下を記述

@Component({
  components: {
    ValidationProvider
  }
})

・フォームをValidationProviderで囲う

<ValidationProvider
  name = "clientName" //ここでしたいしたnameでエラーを呼び出せる
  rules = "required"
  v-slot = "{ errors }" //errorsに配列でエラーオブジェクトが格納される
  :immediate = "true" //即時判定する
>
  <input
    type="text"
    name="名前" //エラーメッセージに使用できる
    value="clientName"
    v-model="clientName"
  >
  <p v-show="errors.length">{{ errors[0] }}></p>  //エラーがあったらメッセージを表示
  <div>
    <button @click.prevent="validate(errors)" class="btn btn-basic">次へ</button>
  </div>
</ValidationProvider>

・エラーメッセージのカスタマイズ
extendしている中でカスタマイズする。

extend('required', {
  ...required,  //requiredを継承
  message: '※{_field_}は必須項目です'  //fieldにはinput内で指定s多name属性の値が代入される
})

・フォーム全体にエラーがあるかを監視する:ValidationObserver

<ValidationObserver
  ref = "observer"
  v-slot = "{ invalid }"  //子のValidationProviderにエラーがある場合invalidがtrueとなる
>
  <ValidationProvider>
  </ValidationProvider>

★ドキュメントでは以下のような記述が見つかるが廃止されている

v-validate="required"  //廃止
rules="required"  //OK

※ ValidationProviderをimportする必要があるので注意

【クラスオブジェクトの使用】

クラス定義はexport defaultする前に記載する

<script lang="ts">
import ~~

class Sample {
  id: number
  title: string

  constructor(id: number, title: string) {
    this.id = id
    this.title = title
  }
}

export default ~~

【Watch】

プロパティの値の変更を監視して、変更があった場合に処理を行う

@Watch('questions', { deep: true} ) //第2引数に設定プロパティを指定できる
questionChangeDeep () {
  console.log('catch');
}

■設定プロパティ
deep: <真偽値> //監視する値がオブジェクトの場合など、ネストされたプロパティの値を監視する
immediate: <真偽値> //初期読み込み時にも実行するか

■複数プロパティの監視
配列にして監視する

//算出プロパティを作成し監視する要素を配列にまとめる
get watchTarget () {
  return [this.param1, this.param2]
}

@Watch('watchTarget')
propChanged () {
  this.fillData()
}

【関数】

@Watch('point') //ラジオボタンなどプロパティを動作検知する場合はWatch
@Emit('sumUp')
sumUp () {
  this.sumPoint += this.point
}

【mounted】

ライフサイクルフックの一つ。
Vueではインスタンスが作られてから削除されるまでにフックとして処理を挿入できる。
vue.jsのcreatedとmountedの違いを目で見て理解 | アールエフェクト
つまりはVueインスタンスメソッド

【vue-chart.js】

■参考
基本:https://belltree.life/vue-chartjs/
インストール:Vue.js+Chart.jsプロジェクト - Qiita
リアルタイム更新:やたら易しいvue-chart.js解説 | 謎の技術研究部
親子プロパティ連携:Vue.js(ts)でvue-chartjsを使う - Qiita

■基本
・読み込まれる子コンポネントはvue-chartjsによって作られるためを一切記述しないこと

・Propの受け取り
チャートでは子コンポーネントとして作成し、親コンポーネントから読み込むのが一般的な運用。
その中で、chartData、optionsを親コンポーネントから受け取る。
子コンポーネントでは@Propを使用して値を受け取るが、デフォルトの型はvue-chartjsではなくchart.jsから読み込む。

@Component
export default ~~
  @Prop()
  public chartData!: Chart.ChartData;

  @Prop()
  public options: Chart.ChartData;

  @Prop()
  public options!: Chart.ChartOptions;

・vue-property-decoratorのMixisと、vue-chartjsのmixins

・親子コンポネント間のプロパティの共有
vue-chartjsのmixinsオプションのプロパティであるreactivePropを設定するのみ。
これで自動的に監視用のプロパティを作成してwatchしてくれる

<script lang="ts">
import [ Component, Prop, Mixins, Vue ] from 'vue-property-decorator'
import Chart from 'chart.js'
import [ Radar, mixins ] from 'vue-chartjs'

@Component
export default class RadarChart extends Mixins(Radar, mixins,.reactiveProp, Vue) {

  @Prop()
  public chartData!: Chart.ChartData;

  @Prop()
  public options!: Chart.ChartOptions;
}

■エラー
・Object is possibly 'undefind'
@Prop
arr = [];
と定義すると、未定義の可能性があります、とのエラー。
arr = Array とすると解消したが、根本的な解決にはなっていない気がする…

・chart_js__WEBPACK_IMPORTED_MODULE_0__.default is not a constructor
Chart.jsは大きなアップデートがあり、vue-chartjsが対応できていない
参考:
vue-chartjsでグラフが表示されない問題 - Qiita

・Property 'extends' has no initializer and is not definitely assigned in the constructor.
vue-chartjsのドキュメントによると、chartTypeを読み込む際に、vueインスタンスのオプションであるextendsに以下のようにアクセスする。

import [ Radar ] from 'vue-chartjs'
<script>
@Component
export default () {
  extends: Radio
}
</script>

しかし、この記述方法ではtypescriptを導入している場合、記述仕様上、extendsがプロパティとして認識されてしまいエラーになる。

>Mixinsを利用して以下のように記述する。

<script lang="ts">
import [ Component, Prop, Mixins, Vue ] from 'vue-property-decorator'
import [ Radar ] from 'vue-chartjs'

@Component
export default class RadarChart extends Mixins(Radar, Vue) {
}

・Chartjsが見つからない
"export 'default' (imported as 'Chart') was not found in 'chart.js'
参考:
Vue.jsでchart.jsが入らない - Qiita
バージョンの問題らしい。参考をもとにchart.js系のバージョンを指定して入れなおしたら解消した。

【Vue.jsの導入、プロジェクトの開始】

■Vue.jsの導入
参考:
【Vue.js】10分でできる! ~ Vue.jsのインストール → プロジェクト作成と起動まで~ - Qiita

・Node.jsのインストール
Vue.jsはNode.jsの環境を使用したフレームワークであるため、まずはNode.jsのインストールが必要となる。
Node.js

・Node.jsバージョン確認

node --version

これでnpmコマンドが使用できるようになった

・vue-cliのインストール
vueコマンを使用できるようにする

npm install -g @vue/cli  //-gでグローバル領域にインストール ※これをしないとパッケージ単位でしかインストールされない

・vue-cliバージョン確認

vue --version

これでvueコマンドが使用できるようになった

■プロジェクトの開始
参考:
vue.js + typescript = vue.ts ことはじめ - Qiita

・プロジェクトの作成

vue create プロジェクト名
Mnually select features を選択

Babel, TypeScript, Router を選択 ※スペースで切り替え
vuexも入れておいた方がよさそう
あとは好みで設定。全部yesでもOK
参考:
【Vue.js】vue-cliを使ってプロジェクトを作成し起動するまでの手順|teamnp|note
Pick a linter はstanderdが無難?
Pick additional lint featuresはLint on save
Where do you prefer placing config //コンフィグの設定場所
Save this as a preset for future projects? //今回の設定を次回も使用できるようにする?

【appendics】

■各コンポーネントはクラスとなる

■プロパティの定義

<script>
data : {
  name: string;
}

上記のように記載することで、クラスプロパティとして定義できる。
typescriptの場合はdataの記載は必要なく、以下のようにプロパティのみでよい

<script lang="ts">
name: string;

ちなみに以下のようにすると、型が明らかなので型宣言しないようにとのエラーが出る

name: string = 'sample';  //エラー
name = 'sample';  //エラーなし

宣言を明確にしたい場合は2行に分ける

name: string;
name = 'sample';

■normalize.css
・インストール

npm install --save normalize.css

・App Vueでimport

<script>
import 'normalize.css'

export default {
  name: 'App'
}
</script>

・確認
デベロッパーツール>Sourcesタブ
以下のパスでnormalize.cssが読み込まれているか

webpack://>.>node_modules>normalize.css

■画像(静的)読み込み
assetsフォルダに配置する

・cssで呼び出す

background-image: url("../assets/img/shadow.png");

■install --save の--saveとは?
以前まではこの--saveオプションをつけないとpackage.jsonのdependenciesに記述されなかった。
現在では、自動で記述されるため不要のはず

■export defaultとvue-property-decorator

export  //これで他のファイルからimportできるようになる
default  //exportするファイルに名前を付けなくても良くなる?※パス指定だけで呼び出せる?

参考:
はじめてのvue-property-decorator (nuxtにも対応) - Qiita
Vue + typescript について (vue-class-component, vue-property-decorator って何?) - Qiita

そもそもVueでTypescriptを導入するために『vue-class-component』を導入している。
これにより、各vueファイルでVueを継承したクラスコンポーネントとして扱うことができる。
この時点ではこのコンポーネントの定義、componentsやpropsを@Componentや、@Optionsの引数内に定義する。

import Vue from 'vue'  //Node.jsのファイルからvueの仕様をインポート…①
import Component from 'vue-class-component'
@Component({
  components: ●●  //子コンポーネント
  props: ●● //親から引き継ぐプロパティ
})
export default class Sample extends Vue {
}

これを使い勝手良くしたものがvue-property-decorator。
上記の①のインポートや、@Component内に記述していたPropsを@Propsとしてクラスコンポーネントのメンバーとして記述できるようにする機能を一手にimportできる。

import { Component, Vue, Prop } from 'vue-property-decorator'
@Component({})
export default class Sample extends Vue {
}

・vue-property-decoratorのインストール

npm i -S vue-property-decorator

■ページ遷移時にスクロールトップ
/router/index.ts

const router = new VueRouter({
  ~~~
  scrollBehavior (to, from, savePosition) {
    if (savePosition) {
      return savePosition
    } else {
      return { x: 0, y: 0 }
    }
  }
})

■フェードイン
~App.vue~

<template>
  <transition>  //transitionで囲う
    <router-view></router-view>
  </transition>
</template>

.v-enter-active {
  transition: opacity 0.5s 0.5s;
}
.v-enter {
  opacity: 0;
}
.v-leave-active {
  transition: opacity 0.5s;
}
.v-leave-to {
  opacity: 0;
}

※ただし、スクロールトップとか入れていると、消える前にスクロールトップしてしまうので調整が必要

【エラー対応ログ】

■Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value.
親コンポーネントからもらってきたpropsを上書きしないでくれ!
親コンポーネントとの差異が出てしまうよ!

>対処法はEmitの項目を参照

■Property '●●' has no initializer and is not definitely assigned in the constructor.
プロパティ●●が初期化されていないよ!
でも@Propsで親コンポーネントからわたってくる値だから初期化できないが…
そんな時は、確実に親コンポーネントからわたってくる値だよ!を示すアサーションを付ける

@Props()
content!: string;
  //『!』がアサーション。必ず親からプロパティがわたってくることを保証する。
  //『?』に置き換えると、わたってこない可能性があることを示す。

■Emit is not defined
定義されていないよ!

import { Component, Prop, Emit, Vue } from 'vue-property-decorator'  //ちゃんとEmitをインポートする

■ERR_CONNECTION_TIMED_OUT
Wifiなどネットワーク環境を切り替えると発生する?
ブラウザを再起動したら解消した

■Declaration expected
宣言して!
publicとか書けってこと?

■特定のIPにデプロイしたが

でルーティングしているコンポーネントが表示されない。

以下の2カ所を修正したところ表示された。が、これだとlocalhostでは表示されない…
~vue.config.js~を作成

module.exports = {
  publicPath: '/AppName/'
}

※通常は『./』で相対パスにするが、なぜかコードに反映されない
../AppName/で無理やりやるとコードには反映されるが、相変わらずルーターには認識されない

このときは絶対パスにして解決したが、根本的な解決にはなっていない。

参考になるかも
【Vue.js】historyモードにした際の注意点 | 集の一期一会

■No overload matches this call
Type 'number' is not assignable to type 'string'.

this.$router.pushしようとしたらエラー。
param1はthisでも子コンポーネントでもnumberで一致している。

this.$router.push({
  name: 'Result',
  params: {
    param1: this.param1
  }
})

>>パラメータはすべて文字列になる?
参考:
parameters - Vue + Typescript vue-router and type of params - Stack Overflow

param1: String(this.param1)としたらエラーは解消した。

■parameter 'param1' implicity has an 'any' type.
型が定義されていないよ!暗黙的にはanyと思われるよ
以下のように型が未知の引数を指定したときに発生

filters: {
  varidator (param1) {  //ここでエラー
    if (!param1) return ''
    return param1
  }
}

param1: string など型指定してあげる

■ラジオボタンにをかけると無限ループになる
Multiple v-models/values inside validation provider gives infinite loop · Issue #2638 · logaretm/vee-validate · GitHub

これによると、入力検地を無効化することができる?ただ、それを可能にするドキュメントはなかった。
vuetifyを使えばいけるのだろうか

■Property 'XXX' does not exist on type 'YYY'
型YYYにはプロパティXXXは存在しないよ
参考:
VueJS with typescriptでしばしば遭遇するProperty 'XXX' does not exist on type 'CombinedVueInstanceの解消法 - Qiita
わかりにくいが、YYYの型が型推論できていないからちゃんと型を定義してね、ということらしい。
特にthisをつかって自身のコンポーネントを指すときになぜか自身の型がわからなくなっちゃうらしい。
厳密にはエラーとなっているYYYの型を調べて as 型 で定義する。
てっとり早い解決策としては as any とする。

例)
エラー個所

export default class Category extends Vue {
  ~~~
  this.questions[i].selectedPoint
  ~~~
}

エラーメッセージ

Property 'selectedPoint' does not exist on type 'never'.

this.questions[i]が型neverと判定されている。
thisの型をanyにすると解消した。

(this as any).questions[i].selectedPoint

■Duplicate keys detected: '1'. This may cause an update error.
v-forを使用したときのkey重複エラー。

【検索ワード】

Type number trivially inferred from a number literal, remove type annotation
trivially inferred from エラーにしない
★radio v-for v-model
setter
子コンポーネント プロパティ 書き換え
PropTypeとは

Python備忘録

【基本操作】

■日時・日付

print(datetime.date.today())  #2017-11-08
print(datetime.datetime.today())  #2017-11-08 23:58:55.230546

■文字列変換

str(val)

■コンソール出力

print('text')

改行は\n

■javascriptの実行

driver.execute_script('somescript')

■文字列に変数を埋め込む(テンプレートリテラル)

print('%s' + '%s' % (山田, くん)) #山田くん
.format()
f'~{hensu}~'

■リストに要素を追加する

mylist.append('ELM')

【関数】

■While文

while i < 3:
    print(i)
    i += 1

【exe化】

pyinstallerを使用すると簡単にexeファイルにまとめることができる。
配布先にdriverが無くても動作する。
参考:
【超簡単】Python プログラムを pyinstaller で EXE化しよう | 趣味や仕事に役立つ初心者DIYプログラミング入門

pip install pyinstall

・exe化

pyinstaller ●●.py --onefile

※driverを使用している場合は同階層にコピーして置いておく
※フォルダをまたいで複数ファイルで構成されていたとしてもルートとなるファイルを1つ指定すれば、その中のimportの記述から適切に1つのファイルにまとめてくれる。
※distなどフォルダ、ファイルが多々作成されるが、すべて削除してもexeファイルのみで動作する。


【ファイル・フォルダ操作】

■カレントディレクトリを取得

import os
os.getcwd()

■パスの操作

os.path  #この中のメソッドで相対パス、絶対パスなどカスタムできる

■ユーザーエージェント情報の取得

import getpass
getpass.getuser()  #ユーザ名を取得

■フォルダ作成

os.makedirs(path, exist_ok=True)  #すでにフォルダが存在した場合もエラーにしない

■ファイル・フォルダ削除 #中にファイルが存在しても削除可能

shutil.rmtree(pass)

■ファイル・フォルダ移動

shutil.move(from_path, to_path)

■名前を変更、リネーム

os.rename(file_path, new_path)

■ファイルの検索

import glob
file = glob.glob(f'C:/Users/{変数}/*')  #ワイルドカード使用可能

■Excel操作

wb = openpyxl.load_workbook('URL.xlsx')

・シートを選択

ws = wb['URL']

・最終行を取得

end_row = ws.max_row

・各行のセルの値を配列に格納

for i in range(2, end_row + 1, 1):
  arr.append(ws.cell(row=i, column=1).value)

・閉じる

wb.close()

・ソート

arr.sort()

■印刷

driver.execute_script('window.print()')  #javascriptで印刷する

■csvで出力
・基本形

write_obj = csv.witer(open('output.csv','r')) #csvファイルを開きwriterオブジェクトに変換
write_obj.writerow(li)

・ファイルを開く

open('パス/ファイル名','オプション')

※パスの初期値はcd
・オプション

a:追記 w:上書き r:読み取り専用 r+:読み書き

※初期値はr
※新規作成は、指定されたパスに該当するファイルがなければ自動的に新規作成になる

小数のデータ型はfloat
ただ、誤差を含んでいる場合がある
decimalクラスを使うと良い

Eclipseショートカットキー備忘録

【参考】
https://qiita.com/shuntaro_tamura/items/530e5068d48ae6d92fb8
https://qiita.com/arai-wa/items/c2eb7387b5bf37b4ace4


【よく使うショートカットキー】

  • 予測変換 :Ctrl + Space
  • 行削除 :Ctrl+D
  • 行コピー :Ctrl+Alt+↓
  • 移動 :Alt + ↑↓
  • コメントアウト :Ctrl + / Javaファイルじゃない場合はCtrl + Shift + C?
  • 同じ単語を選択 :alt + shift + r
  • 呼び出し元を開く :Ctrl + Alt + h
  • アプリケーション実行 :Ctrl + F11
  • 画面を行ったり来たり :Alt + → or ←
  • 区切りの良い場所へカーソル移動 :Ctrl + → or ←
  • 選択範囲の拡大 :Alt + Shift + ↑ or ↓
  • 次のエラーへジャンプ :Ctrl + .
  • grep(ファイル検索) :alt + a -> f
  • import文の一括編成:ctrl + shift + o
  • 右インデント :tab
  • 左インデント :shift + tab
  • インデント整理 :ctrl + shift + f

:Ctrl + i ※インデント箇所を選択してから

  • 検索 :ctrl + h

※画面がさかさまになったりする場合はグラフィックホットキーが効いてしまっている。画面を右クリック >グラフィックプロパティ >ホットキーの有効チェックボックスをOFF

【予測変換設定】

■初期設定では『.』を入力したタイミングで予測変換が実行されるようになっているが、すべての文字をキーにして予測変換が動作するようにする。

ウィンドウ>設定>Java>エディター>コンテンツアシスト>Javaの自動有効化トリガー
初期設定:『.』
変更後:『.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_』

【エラー対応】

■javascriptでコメントアウトのショートカットキーが効かない
JavaのファイルはCtrl + / でコメントアウトができるがjavascriptのファイルに対しては動作しなかった。
Ctrl + Shift + C でコメントアウトできた。
尚、同設定は、ウィンドウ>設定>一般>キー から確認できる。

webデザイン基礎備忘録

画面サイズ

max-width: 800~1000px
min-width: 460px

テキスト

- 級数は3種類までにする
- フォントは14px以上

フォーム

ラジオボタン

- テキスト全体をボタンにするのが主流
- ホバーエフェクト
- 選択されたらホバーエフェクトを固定&議事要素で右側に✓を付ける
- 高さはそろえる

フレームワーク

- マテリアルUI
- bootstrap

stickyfooter //固定フッター
参考:
【BootstrapでWebデザイン】Bootstrapでfooterを作成する方法 | .NETコラム

pythonにSelenium導入備忘録

■必要なもの

Firefoxウェブドライバー:Firefox公式ページ
Python:Python公式ページ
selenium:Pythonのpip
Powershell最新版

■パワーシェルの実行権限
win+r =>powershell
set-executionpolicy remotesigned
Y
上矢印キーを2回押してset-executionpolicy remotesigned
が表示されたら、get-executionpolicyに修正
Enter
remotesignedと表示されればOK
■Pythonのインストール

https://www.python.org/から。
適したバージョンのexecutable installerをダウンロード
Customize installationを選択
pip、Add Python to environment variables(環境変数にパスを通す)を選択

※デフォルトでインストールした場合、インストールされる先は以下
C:\Users\under\AppData\Local\Programs

・バージョン確認

python-V
■Seleniumのインストール

powershellで以下を入力

pip install selenium

Pythonのフォルダの下位層にインストールされる

■Firefoxwebdriver(geckodriver)のインストール

以下のサイトからwin版のドライバをダウンロード
https://github.com/mozilla/geckodriver/releases

Pythonフォルダ内にドライバ(geckodriver.exe)を格納
Python\python**-**