ChatGPTを活用してMSAccess風のHTMLツールのプロトタイプを個人開発してみる

IT技術 AI 生成AI 教養としてのテクノロジー入門

生成AIの開発活用が進んでいます。Github Copilotなど専用のサービスがありますが、ChatGPTも結構しっかりしたプログラムコードを書いてくれます。

先日は、フラクタル図形やアニメーションなどを作らせてみましたが、今回はもっと実用的なWEBツールの開発をしてみようと思います。

目次

今回開発するもの

先日、以下の記事にてFile System Access APIについてご紹介しました。

本題とはずれますが、私自身の周囲では業務環境改善に関して近年File System Access APIが注目されています。これを活用した事務業務のツールを作る前までは、ExcelのVBAやMSAccessを使うことが主流でした。

しかしながら、Macなどの他OSでVBAが動かなかったり、そもそもAccessはWindows限定だったりで環境依存が強いなどの問題が前々からあがっていました。そのため、最注目はPythonですが、もう一つの選択肢としてJavaScriptのHTMLツールが注目されています。

今回は、上述の記事に関連して、MsAccessの代替になるようなツールを作ることを挑戦してみたいと思います。

ChatGPTに依頼する仕様

いきなりMsAccessすべての機能を使えるツールを作るのは依頼文をつくるのも大変です。そのため、今回は以下のような簡単な仕様でプロトタイプを作れるか依頼してみます。

依頼する文章はこのようにしてみました。

ChatGPTに依頼した結果

ChatGPTに依頼したところ以下のような回答をしてくれました。ちなみに表現など開けたり追加の指示をしたのですが、残念ながらGPT3.5では動くものや要件通りのものは作れず、GPT4を利用しました。

 

実際に書いてもらったコードはこちらです。


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple Database Tool</title>
    <script>
        let database = {};

        // Function to create a new table
        function createTable() {
            const tableName = document.getElementById("tableName").value;
            const columns = document.getElementById("columns").value.split(",");
            database[tableName] = { "columns": columns, "rows": [] };
            displayTables();
        }

        // Function to insert a new row into a table
        function insertRow() {
            const tableName = document.getElementById("insertTable").value;
            const rowData = document.getElementById("rowData").value.split(",");
            if (database[tableName]) {
                database[tableName].rows.push(rowData);
                displayTables();
            } else {
                alert("Table does not exist.");
            }
        }

        // Function to display tables
        function displayTables() {
            const display = document.getElementById("tableDisplay");
            display.innerHTML = "";
            for (const [tableName, table] of Object.entries(database)) {
                let html = "<h3>" + tableName + "</h3>";
                html += "<table border='1'><tr>";
                for (const col of table.columns) {
                    html += "<th>" + col + "</th>";
                }
                html += "</tr>";
                for (const row of table.rows) {
                    html += "<tr>";
                    for (const cell of row) {
                        html += "<td>" + cell + "</td>";
                    }
                    html += "</tr>";
                }
                html += "</table><br>";
                display.innerHTML += html;
            }
        }

        // Function to save the database as a JSON file
        async function saveDatabase() {
            const handle = await window.showSaveFilePicker({
                suggestedName: 'database.json',
                types: [{
                    description: 'JSON Files',
                    accept: {'application/json': ['.json']}
                }]
            });
            const writable = await handle.createWritable();
            await writable.write(JSON.stringify(database));
            await writable.close();
        }

        // Function to load a database from a JSON file
        async function loadDatabase() {
            [fileHandle] = await window.showOpenFilePicker({
                types: [{
                    description: 'JSON Files',
                    accept: {'application/json': ['.json']}
                }]
            });
            const file = await fileHandle.getFile();
            const text = await file.text();
            database = JSON.parse(text);
            displayTables();
        }
    </script>
</head>
<body>
    <h1>Simple Database Tool</h1>
    <div>
        <h2>Create Table</h2>
        <input type="text" id="tableName" placeholder="Table Name">
        <input type="text" id="columns" placeholder="Column1,Column2,...">
        <button onclick="createTable()">Create Table</button>
    </div>
    <div>
        <h2>Insert Row</h2>
        <input type="text" id="insertTable" placeholder="Table Name">
        <input type="text" id="rowData" placeholder="Data1,Data2,...">
        <button onclick="insertRow()">Insert Row</button>
    </div>
    <div>
        <h2>Database</h2>
        <div id="tableDisplay"></div>
    </div>
    <div>
        <button onclick="saveDatabase()">Save Database</button>
        <button onclick="loadDatabase()">Load Database</button>
    </div>
</body>
</html>

実際の動作ツールの画面はこちらです。

 

ちゃんと作ってくれました。file system access apiによるデータ保存、データ読み込みもやってくれます。コンマ区切りでフィールド定義を簡略化したりこの辺りのテクニックも考えてくれるようです。

Microsoft Copilotで試してみる

ChatGPTだと有料のGPT4が必要でした。GPT4は無料のMicrosoft Copilotでも使えるのでこちらでも試してみました。

 

作成いただいたコードの全文はこちらです。


<!DOCTYPE html>
<html>
<body>
    <button id="create">テーブル作成</button>
    <button id="insert">データ挿入</button>
    <button id="view">データ閲覧</button>
    <button id="save">保存</button>
    <button id="load">読み込み</button>
    <div id="output"></div>
    <script>
        let db = {};
        document.getElementById('create').addEventListener('click', () => {
            let tableName = prompt('テーブル名を入力してください');
            let columns = prompt('列名をカンマで区切って入力してください').split(',');
            db[tableName] = { columns, rows: [] };
            alert('テーブルが作成されました');
        });
        document.getElementById('insert').addEventListener('click', () => {
            let tableName = prompt('データを挿入するテーブル名を入力してください');
            if (!db[tableName]) {
                alert('テーブルが存在しません');
                return;
            }
            let row = {};
            for (let column of db[tableName].columns) {
                row[column] = prompt(`${column}の値を入力してください`);
            }
            db[tableName].rows.push(row);
            alert('データが挿入されました');
        });
        document.getElementById('view').addEventListener('click', () => {
            let tableName = prompt('データを閲覧するテーブル名を入力してください');
            if (!db[tableName]) {
                alert('テーブルが存在しません');
                return;
            }
            document.getElementById('output').innerText = JSON.stringify(db[tableName].rows, null, 2);
        });
        document.getElementById('save').addEventListener('click', async () => {
            let fileHandle = await window.showSaveFilePicker();
            let writable = await fileHandle.createWritable();
            await writable.write(JSON.stringify(db));
            await writable.close();
            alert('データが保存されました');
        });
        document.getElementById('load').addEventListener('click', async () => {
            let [fileHandle] = await window.showOpenFilePicker();
            let file = await fileHandle.getFile();
            let text = await file.text();
            db = JSON.parse(text);
            alert('データが読み込まれました');
        });
    </script>
</body>
</html>

実際の動作ツールの画像は以下です。

 

こちらもちゃんと動くコードを書いてくれました。コンマ区切りという点は共通ですが、Alertを活用した対話方式でデータ入力させたり、JSONをそのまま表示するという形式という点、日本語表記などの違いがありました。

有料版が使えない人はCopilotを使うと良いかもしれません。

今後の方向

今回はプロトタイプです。ここからデザインを綺麗にしたり、削除やViewなどを追加すれば本当に実用できるものが開発できそうです。

ここからの開発はChatGPTに依頼して修正コードを作ってもらうために、依頼を作るコストと、自分で作るコストどっちがかかるかどうかは検証する必要がありそうです。

あくまで趣味の個人開発なので、ゆっくりペースですが今後こちらも試してみたいと思います。

終わりに

最後まで読んでいただきありがとうございました。ChatGPTや生成AIツールの活用の参考になれば幸いです。

Photo by: Nicole De Khors on burst

 みやうデジタルラボ - にほんブログ村