0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

メモ帳家計簿data テキストboxで一括コピペ

Posted at

仕組み : dataを改行 / カンマ / タブ /文字列 /数字 に分ける
1行ずつ処理。
「日付 :」で新しい日付ブロック開始。
日付に 品目・金額の行 紐付け。
金額 : 行末と中央の数字を抽出。
品目 : 数字を除いた残りの部分。
→ 2次元配列 or オブジェクト配列に加工

合計金額 parseIntで取り出し、total +=で足す。
NaNチェックつける。
サーバー保存 axios.post(URL, data)でJSON送信。
品目 数字を除いた残りを item に
既存データをクリアしてから全件保存
→ HTMLにテーブル表示

入れたいdata

  3 : トマト / 2.      317

  4  :   疲れてヨーグル. 54

          124     洗濯機汚とり.  110
             
        コーヒー + ジュース108

        ジュース×.2  ノート.  201                           
        梅酒.   114 
JSのみのcode
<textarea id="inputBox" rows="15" cols="60" placeholder="ここにメモ帳の内容を貼る"></textarea>
<button onclick="parseMemo()">変換して表示</button>
<table id="output" border="1"></table>

<script>
function parseMemo() {
  const raw = document.getElementById("inputBox").value;
  const lines = raw.trim().split("\n");

  let currentDate = "";
  const result = [];

  lines.forEach(line => {
    line = line.trim();
    if (line === "") return;

    // 日付の行(例: "2 :")
    const dateMatch = line.match(/^(\d{1,2})\s*:/);
    if (dateMatch) {
      currentDate = dateMatch[1];
      line = line.replace(/^(\d{1,2})\s*:\s*/, "");
    }

    // 数字(=金額)を抽出
    const amountMatch = line.match(/(\d{2,5})(?!\d)/); // 例: 317, 1207など
    const amount = amountMatch ? amountMatch[1] : "";

    // 品目(数字を除いたテキスト)
    const item = line.replace(/(\d{2,5})(?!\d)/g, "").trim();

    if (item || amount) {
      result.push({ date: currentDate, item, amount });
    }
  });

  // 表に表示
  const table = document.getElementById("output");
  table.innerHTML = "<tr><th>日付</th><th>品目</th><th>金額</th></tr>";
  result.forEach(row => {
    const tr = document.createElement("tr");
    ["date", "item", "amount"].forEach(key => {
      const td = document.createElement("td");
      td.textContent = row[key];
      tr.appendChild(td);
    });
    table.appendChild(tr);
  });
}
</script>

完成系 (idb保存)

<textarea id="inputBox" rows="15" cols="60" placeholder="ここに家計簿メモを貼る"></textarea>
<br>
<button onclick="parseMemo()">変換して表示 & 保存</button>
<p id="total"></p>
<table id="output" border="1"></table>

<script>
const DB_NAME = 'kakeiboDB';
const STORE_NAME = 'entries';

// IndexedDBを開く・作る
function openDB() {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, 1);
    request.onupgradeneeded = () => {
      const db = request.result;
      if (!db.objectStoreNames.contains(STORE_NAME)) {
        db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });
      }
    };
    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
}

// IndexedDBに保存
async function saveToIDB(dataArray) {
  const db = await openDB();
  return new Promise((resolve, reject) => {
    const tx = db.transaction(STORE_NAME, 'readwrite');
    const store = tx.objectStore(STORE_NAME);

    // まず全部クリアしてから新規保存する(上書き)
    const clearReq = store.clear();
    clearReq.onsuccess = () => {
      // 配列の各アイテムをput
      dataArray.forEach(item => store.put(item));
    };
    clearReq.onerror = e => reject(e.target.error);

    tx.oncomplete = () => resolve();
    tx.onerror = e => reject(e.target.error);
  });
}

async function parseMemo() {
  const raw = document.getElementById("inputBox").value;
  const lines = raw.trim().split("\n");

  let currentDate = "";
  const result = [];
  let total = 0;

  lines.forEach(line => {
    line = line.trim();
    if (line === "") return;

    const dateMatch = line.match(/^(\d{1,2})\s*:/);
    if (dateMatch) {
      currentDate = dateMatch[1];
      line = line.replace(/^(\d{1,2})\s*:\s*/, "");
    }

    const amountMatch = line.match(/(\d{2,5})(?!\d)/);
    const amount = amountMatch ? parseInt(amountMatch[1]) : null;

    const item = line.replace(/(\d{2,5})(?!\d)/g, "").trim();

    if (item || amount) {
      result.push({ date: currentDate, item, amount });
      if (!isNaN(amount)) total += amount;
    }
  });

  const table = document.getElementById("output");
  table.innerHTML = "<tr><th>日付</th><th>品目</th><th>金額</th></tr>";
  result.forEach(row => {
    const tr = document.createElement("tr");
    ["date", "item", "amount"].forEach(key => {
      const td = document.createElement("td");
      td.textContent = row[key] || "";
      tr.appendChild(td);
    });
    table.appendChild(tr);
  });

  document.getElementById("total").textContent = `合計金額: ${total} 円`;

  // IndexedDBに保存
  try {
    await saveToIDB(result);
    console.log("IndexedDBに保存成功");
  } catch (e) {
    console.error("IndexedDB保存エラー:", e);
  }
}
</script>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?