Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C#ใงExcelใ‚ขใƒ‰ใ‚คใƒณ ร— PostgreSQL ร— VBA: ExcelใงPostgreSQLใ‚’ๆ‰ฑใ†Tips

3
Last updated at Posted at 2024-11-08

Excelใ‚ขใƒ‰ใ‚คใƒณใงPostgreSQLใซๆŽฅ็ถšใ™ใ‚‹ๅฎŸ่ฃ…ใซใคใ„ใฆใ€ใ‚ˆใ‚Š่ฉณใ—ใ่งฃ่ชฌใ—ใŸ่จ˜ไบ‹ใ‚’ไฝœๆˆใ—ใพใ™ใ€‚

Excelใ‹ใ‚‰PostgreSQLใซๆŽฅ็ถšใ™ใ‚‹ใ‚ขใƒ‰ใ‚คใƒณใฎ้–‹็™บ - ๅฎŸ่ฃ…่ฉณ่งฃ

ใฏใ˜ใ‚ใซ

Excelใ‹ใ‚‰PostgreSQLใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใซๆŽฅ็ถšใ—ใ€SQLใ‚ฏใ‚จใƒชใ‚’ๅฎŸ่กŒใ—ใฆ็ตๆžœใ‚’Excelใ‚ทใƒผใƒˆใซๆ›ธใ่พผใ‚€ๆ–นๆณ•ใ‚’็ดนไป‹ใ—ใพใ™ใ€‚ODBCใƒ‰ใƒฉใ‚คใƒใ‚’ใ‚คใƒณใ‚นใƒˆใƒผใƒซใงใใชใ„็’ฐๅขƒใงใ‚‚ๅ‹•ไฝœใ™ใ‚‹ใ‚ˆใ†ใ€C#ใจExcel DNAใƒฉใ‚คใƒ–ใƒฉใƒชใ‚’ไฝฟใฃใฆExcelใ‚ขใƒ‰ใ‚คใƒณใ‚’ไฝœๆˆใ—ใพใ™ใ€‚ใ“ใฎ่จ˜ไบ‹ใงใฏใ€็‰นใซC#ใฎๅฎŸ่ฃ…้ƒจๅˆ†ใซใคใ„ใฆ่ฉณใ—ใ่งฃ่ชฌใ—ใพใ™ใ€‚

ๅฟ…่ฆใช็’ฐๅขƒใจใƒฉใ‚คใƒ–ใƒฉใƒช

้–‹็™บ็’ฐๅขƒ

  • Visual Studio 2019ไปฅ้™
  • .NET Framework 4.7.2ไปฅ้™
  • Microsoft Excel (2013ไปฅ้™ๆŽจๅฅจ)

ๅฟ…่ฆใชNuGetใƒ‘ใƒƒใ‚ฑใƒผใ‚ธ

- ExcelDna.AddIn
- ExcelDna.Integration
- Npgsql
- Microsoft.Office.Interop.Excel

ๅฎŸ่ฃ…ใฎ่ฉณ็ดฐ่งฃ่ชฌ

1. ๅŸบๆœฌๆง‹้€ ใจใ‚ฏใƒฉใ‚น่จญ่จˆ

using System;
using System.Data;
using System.Runtime.InteropServices;
using Npgsql;
using ExcelDna.Integration;
using Excel = Microsoft.Office.Interop.Excel;

namespace PostgresExcelAddin
{
    public static class Functions
    {
        private static NpgsqlConnection _connection;
        // ...
    }
}

ใ“ใฎ้ƒจๅˆ†ใง้‡่ฆใชใƒใ‚คใƒณใƒˆ๏ผš

  • ExcelDna.Integrationๅๅ‰็ฉบ้–“๏ผšExcel DNAใฎๆฉŸ่ƒฝใ‚’ไฝฟ็”จใ™ใ‚‹ใŸใ‚ใซๅฟ…่ฆ
  • Npgsql๏ผšPostgreSQLๆŽฅ็ถš็”จใฎใƒฉใ‚คใƒ–ใƒฉใƒช
  • Microsoft.Office.Interop.Excel๏ผšExcelใฎCOMใ‚คใƒณใ‚ฟใƒผใƒ•ใ‚งใƒผใ‚น็”จ
  • static NpgsqlConnection _connection๏ผšใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นๆŽฅ็ถšใ‚’ไฟๆŒใ™ใ‚‹้™็š„ใƒ•ใ‚ฃใƒผใƒซใƒ‰

2. ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นๆŽฅ็ถšๆฉŸ่ƒฝใฎๅฎŸ่ฃ…

[ExcelFunction(Description = "PostgreSQLใซๆŽฅ็ถšใ—ใพใ™")]
public static string ConnectDB(string host, string database, string username, string password, string port = "5432")
{
    try
    {
        var connectionString = $"Host={host};Port={port};Database={database};Username={username};Password={password}";
        
        // ๆ—ขๅญ˜ใฎๆŽฅ็ถšใ‚’ใ‚ฏใƒชใƒผใƒณใ‚ขใƒƒใƒ—
        if (_connection != null && _connection.State == ConnectionState.Open)
        {
            _connection.Close();
            _connection.Dispose();
        }

        // ๆ–ฐใ—ใ„ๆŽฅ็ถšใ‚’็ขบ็ซ‹
        _connection = new NpgsqlConnection(connectionString);
        _connection.Open();
        return "ๆŽฅ็ถšๆˆๅŠŸ";
    }
    catch (Exception ex)
    {
        return $"ๆŽฅ็ถšใ‚จใƒฉใƒผ: {ex.Message}";
    }
}

้‡่ฆใชใƒใ‚คใƒณใƒˆ๏ผš

  • [ExcelFunction]ๅฑžๆ€ง๏ผšใ“ใฎ้–ขๆ•ฐใ‚’Excelใ‹ใ‚‰ๅ‘ผใณๅ‡บใ—ๅฏ่ƒฝใซใ™ใ‚‹
  • ๆŽฅ็ถšๆ–‡ๅญ—ๅˆ—ใฎๆง‹็ฏ‰๏ผšใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃไธŠใฎ็†็”ฑใ‹ใ‚‰ใ€ใƒ‘ใƒฉใƒกใƒผใ‚ฟๅŒ–ใ•ใ‚ŒใŸๆ–นๅผใ‚’ไฝฟ็”จ
  • ๆ—ขๅญ˜ๆŽฅ็ถšใฎ้ฉๅˆ‡ใช็ ดๆฃ„๏ผšใƒกใƒขใƒชใƒชใƒผใ‚ฏใ‚’้˜ฒใ
  • ใ‚จใƒฉใƒผใƒใƒณใƒ‰ใƒชใƒณใ‚ฐ๏ผšไพ‹ๅค–ใ‚’ใ‚ญใƒฃใƒƒใƒใ—ใฆใƒฆใƒผใ‚ถใƒผใƒ•ใƒฌใƒณใƒ‰ใƒชใƒผใชใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’่ฟ”ใ™

3. ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นๅˆ‡ๆ–ญๆฉŸ่ƒฝ

[ExcelFunction(Description = "PostgreSQLใ‹ใ‚‰ๅˆ‡ๆ–ญใ—ใพใ™")]
public static string DisconnectDB()
{
    try
    {
        if (_connection != null)
        {
            if (_connection.State == ConnectionState.Open)
            {
                _connection.Close();
            }
            _connection.Dispose();
            _connection = null;
        }
        return "ๅˆ‡ๆ–ญๆˆๅŠŸ";
    }
    catch (Exception ex)
    {
        return $"ๅˆ‡ๆ–ญใ‚จใƒฉใƒผ: {ex.Message}";
    }
}

ๅฎŸ่ฃ…ใฎใƒใ‚คใƒณใƒˆ๏ผš

  • ๆŽฅ็ถš็Šถๆ…‹ใฎใƒใ‚งใƒƒใ‚ฏ
  • ใƒชใ‚ฝใƒผใ‚นใฎ้ฉๅˆ‡ใช่งฃๆ”พ
  • nullๅ‚็…งใฎ้˜ฒๆญข

4. ใ‚ฏใ‚จใƒชๅฎŸ่กŒๆฉŸ่ƒฝ

[ExcelFunction(Description = "SQLใ‚ฏใ‚จใƒชใ‚’ๅฎŸ่กŒใ—ใฆใ‚ทใƒผใƒˆใซ็ตๆžœใ‚’ๆ›ธใ่พผใฟใพใ™")]
public static object ExecuteQuery(string query, string sheetName)
{
    try
    {
        // ๆŽฅ็ถšใƒใ‚งใƒƒใ‚ฏ
        if (_connection == null || _connection.State != ConnectionState.Open)
        {
            return "ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใซๆŽฅ็ถšใ•ใ‚Œใฆใ„ใพใ›ใ‚“";
        }

        // Excelๆ“ไฝœใฎใŸใ‚ใฎๆบ–ๅ‚™
        var app = ExcelDnaUtil.Application as Excel.Application;
        Excel.Worksheet sheet;

        // ใ‚ทใƒผใƒˆใฎๅ–ๅพ—ใพใŸใฏไฝœๆˆ
        try
        {
            sheet = app.ActiveWorkbook.Worksheets[sheetName];
        }
        catch
        {
            sheet = app.ActiveWorkbook.Worksheets.Add();
            sheet.Name = sheetName;
        }

        // ใ‚ฏใ‚จใƒชๅฎŸ่กŒใจใƒ‡ใƒผใ‚ฟๅ–ๅพ—
        using (var cmd = new NpgsqlCommand(query, _connection))
        using (var reader = cmd.ExecuteReader())
        {
            var dataTable = new DataTable();
            dataTable.Load(reader);

            // ใ‚ทใƒผใƒˆใฎใ‚ฏใƒชใ‚ข
            sheet.UsedRange.Clear();

            // ใƒ˜ใƒƒใƒ€ใƒผใฎๆ›ธใ่พผใฟ
            for (int i = 0; i < dataTable.Columns.Count; i++)
            {
                sheet.Cells[1, i + 1].Value = dataTable.Columns[i].ColumnName;
            }

            // ใƒ‡ใƒผใ‚ฟใฎไธ€ๆ‹ฌๆ›ธใ่พผใฟ
            var data = new object[dataTable.Rows.Count, dataTable.Columns.Count];
            for (int row = 0; row < dataTable.Rows.Count; row++)
            {
                for (int col = 0; col < dataTable.Columns.Count; col++)
                {
                    data[row, col] = dataTable.Rows[row][col];
                }
            }

            if (dataTable.Rows.Count > 0)
            {
                var range = sheet.Range[
                    sheet.Cells[2, 1], 
                    sheet.Cells[dataTable.Rows.Count + 1, dataTable.Columns.Count]
                ];
                range.Value = data;
            }

            // ๅˆ—ๅน…ใฎ่‡ชๅ‹•่ชฟๆ•ด
            sheet.Columns.AutoFit();
            return $"{dataTable.Rows.Count}่กŒใฎใƒ‡ใƒผใ‚ฟใ‚’ๅ–ๅพ—ใ—ใพใ—ใŸ";
        }
    }
    catch (Exception ex)
    {
        return $"ใ‚จใƒฉใƒผ: {ex.Message}";
    }
}

ๅฎŸ่ฃ…ใฎ้‡่ฆใƒใ‚คใƒณใƒˆ๏ผš

  1. ใƒ‡ใƒผใ‚ฟๅ–ๅพ—ใƒ•ใƒญใƒผ

    • NpgsqlCommandใฎไฝœๆˆ
    • DataReaderใ‚’ไฝฟ็”จใ—ใŸใƒ‡ใƒผใ‚ฟ่ชญใฟๅ–ใ‚Š
    • DataTableใธใฎใƒ‡ใƒผใ‚ฟใƒญใƒผใƒ‰
  2. Excelๆ“ไฝœ

    • ใ‚ทใƒผใƒˆใฎๅญ˜ๅœจ็ขบ่ชใจไฝœๆˆ
    • ๆ—ขๅญ˜ใƒ‡ใƒผใ‚ฟใฎใ‚ฏใƒชใ‚ข
    • ใƒ˜ใƒƒใƒ€ใƒผ่กŒใฎ่จญๅฎš
    • ใƒ‡ใƒผใ‚ฟใฎไธ€ๆ‹ฌๆ›ธใ่พผใฟ๏ผˆใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นๆœ€้ฉๅŒ–๏ผ‰
    • ๅˆ—ๅน…ใฎ่‡ชๅ‹•่ชฟๆ•ด
  3. ใ‚จใƒฉใƒผใƒใƒณใƒ‰ใƒชใƒณใ‚ฐ

    • ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นๆŽฅ็ถš็Šถๆ…‹ใฎ็ขบ่ช
    • Excelๆ“ไฝœๆ™‚ใฎไพ‹ๅค–ๅ‡ฆ็†
    • ใƒฆใƒผใ‚ถใƒผใƒ•ใƒฌใƒณใƒ‰ใƒชใƒผใชใ‚จใƒฉใƒผใƒกใƒƒใ‚ปใƒผใ‚ธ

5. ๆ›ดๆ–ฐ็ณปใ‚ฏใ‚จใƒชๅฎŸ่กŒๆฉŸ่ƒฝ

[ExcelFunction(Description = "UPDATE/INSERT/DELETEใ‚ฏใ‚จใƒชใ‚’ๅฎŸ่กŒใ—ใพใ™")]
public static string ExecuteNonQuery(string query)
{
    try
    {
        if (_connection == null || _connection.State != ConnectionState.Open)
        {
            return "ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใซๆŽฅ็ถšใ•ใ‚Œใฆใ„ใพใ›ใ‚“";
        }

        using (var cmd = new NpgsqlCommand(query, _connection))
        {
            int result = cmd.ExecuteNonQuery();
            return $"{result}่กŒใŒๅฝฑ้Ÿฟใ‚’ๅ—ใ‘ใพใ—ใŸ";
        }
    }
    catch (Exception ex)
    {
        return $"ใ‚จใƒฉใƒผ: {ex.Message}";
    }
}

ๅฎŸ่ฃ…ใฎใƒใ‚คใƒณใƒˆ๏ผš

  • ๆ›ดๆ–ฐ็ณปใ‚ฏใ‚จใƒชใฎๅฎŸ่กŒใซใฏExecuteNonQueryใ‚’ไฝฟ็”จ
  • ๅฝฑ้Ÿฟใ‚’ๅ—ใ‘ใŸ่กŒๆ•ฐใ‚’่ฟ”ๅด
  • ้ฉๅˆ‡ใชใƒชใ‚ฝใƒผใ‚น็ฎก็†๏ผˆusingใ‚นใƒ†ใƒผใƒˆใƒกใƒณใƒˆ๏ผ‰

VBAใ‹ใ‚‰ใฎๅ‘ผใณๅ‡บใ—ๆ–นๆณ•

ExcelใฎVBAใ‹ใ‚‰C#ใงๅฎŸ่ฃ…ใ—ใŸ้–ขๆ•ฐใ‚’ๅ‘ผใณๅ‡บใ™ไพ‹๏ผš

' ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นๆŽฅ็ถš
Sub ConnectToDatabase()
    Dim result As String
    result = Application.Run("ConnectDB", "localhost", "postgres", "username", "password", "5432")
    MsgBox result
End Sub

' ใ‚ฏใ‚จใƒชๅฎŸ่กŒ
Sub ExecuteQueryExample()
    Dim queryResult As String
    queryResult = Application.Run("ExecuteQuery", "SELECT * FROM users", "Results")
    MsgBox queryResult
End Sub

' ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นๆ›ดๆ–ฐ
Sub UpdateDatabase()
    Dim nonQueryResult As String
    nonQueryResult = Application.Run("ExecuteNonQuery", "UPDATE users SET active = true WHERE id = 1")
    MsgBox nonQueryResult
End Sub

' ๅˆ‡ๆ–ญๅ‡ฆ็†
Sub DisconnectFromDatabase()
    Dim disconnectResult As String
    disconnectResult = Application.Run("DisconnectDB")
    MsgBox disconnectResult
End Sub

ใ‚ขใƒ‰ใ‚คใƒณ้–‹็™บๆ™‚ใฎๆณจๆ„็‚น

  1. ใƒ‡ใƒใƒƒใ‚ฐๆ–นๆณ•

    • Visual StudioใงExcelใƒ—ใƒญใ‚ปใ‚นใซใ‚ขใ‚ฟใƒƒใƒใ—ใฆๅฎŸ่กŒๆ™‚ใƒ‡ใƒใƒƒใ‚ฐใŒๅฏ่ƒฝ
    • ใƒ‡ใƒใƒƒใ‚ฐใƒ—ใƒชใƒณใƒˆๆ–‡ใฏDebug.WriteLine()ใ‚’ไฝฟ็”จ
  2. ใ‚จใƒฉใƒผใƒใƒณใƒ‰ใƒชใƒณใ‚ฐ

    • ใ™ในใฆใฎๅ…ฌ้–‹ใƒกใ‚ฝใƒƒใƒ‰ใง้ฉๅˆ‡ใชไพ‹ๅค–ๅ‡ฆ็†ใ‚’ๅฎŸ่ฃ…
    • ใƒฆใƒผใ‚ถใƒผใƒ•ใƒฌใƒณใƒ‰ใƒชใƒผใชใ‚จใƒฉใƒผใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’่ฟ”ใ™
    • ใƒ‡ใƒใƒƒใ‚ฐๆƒ…ๅ ฑใฏ้–‹็™บๆ™‚ใฎใฟ่กจ็คบ
  3. ใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นๆœ€้ฉๅŒ–

    • ๅคง้‡ใƒ‡ใƒผใ‚ฟๅ‡ฆ็†ๆ™‚ใฏไธ€ๆ‹ฌๆ›ธใ่พผใฟใ‚’ไฝฟ็”จ
    • ๆŽฅ็ถšใฎใƒ—ใƒผใƒชใƒณใ‚ฐใ‚’่€ƒๆ…ฎ
    • ไธ่ฆใชใ‚ทใƒผใƒˆๆ“ไฝœใ‚’ๆœ€ๅฐ้™ใซ
  4. ใ‚ปใ‚ญใƒฅใƒชใƒ†ใ‚ฃ่€ƒๆ…ฎไบ‹้ …

    • ๆŽฅ็ถšๆ–‡ๅญ—ๅˆ—ใฎๅฎ‰ๅ…จใช็ฎก็†
    • SQL injectionๅฏพ็ญ–
    • ใ‚จใƒฉใƒผใƒกใƒƒใ‚ปใƒผใ‚ธใงใฎๆฉŸๅฏ†ๆƒ…ๅ ฑๆผๆดฉ้˜ฒๆญข

ใพใจใ‚

ใ“ใฎExcelใ‚ขใƒ‰ใ‚คใƒณใฎๅฎŸ่ฃ…ใซใ‚ˆใ‚Šใ€ไปฅไธ‹ใฎใƒกใƒชใƒƒใƒˆใŒๅพ—ใ‚‰ใ‚Œใพใ™๏ผš

  1. ODBCใƒ‰ใƒฉใ‚คใƒไธ่ฆใงPostgreSQLใซๆŽฅ็ถšๅฏ่ƒฝ
  2. C#ใฎๅž‹ๅฎ‰ๅ…จๆ€งใจใ‚จใƒฉใƒผใƒใƒณใƒ‰ใƒชใƒณใ‚ฐใฎๆฉๆต
  3. Excel DNAใซใ‚ˆใ‚‹็ฐกๅ˜ใช้–ขๆ•ฐใ‚จใ‚ฏใ‚นใƒใƒผใƒˆ
  4. ๅŠน็އ็š„ใชใƒ‡ใƒผใ‚ฟๅ–ๅพ—ใจๆ›ธใ่พผใฟ

ใพใŸใ€ใ“ใฎๅฎŸ่ฃ…ใฏไปฅไธ‹ใฎ็‚นใงๆ‹กๅผตๅฏ่ƒฝใงใ™๏ผš

  • ใƒ‘ใƒฉใƒกใƒผใ‚ฟๅŒ–ใ‚ฏใ‚จใƒชใฎใ‚ตใƒใƒผใƒˆ
  • ใƒˆใƒฉใƒณใ‚ถใ‚ฏใ‚ทใƒงใƒณ็ฎก็†ใฎ่ฟฝๅŠ 
  • ้žๅŒๆœŸๅ‡ฆ็†ใธใฎๅฏพๅฟœ
  • ใ‚ˆใ‚Š่ฉณ็ดฐใชใ‚จใƒฉใƒผใƒญใ‚ฐๆฉŸ่ƒฝ

ใ“ใฎใ‚ขใƒ‰ใ‚คใƒณใฏใ€Excelใƒฆใƒผใ‚ถใƒผใŒPostgreSQLใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใ‚’็ฐกๅ˜ใซๆ“ไฝœใงใใ‚‹ใ‚ˆใ†ใซใ™ใ‚‹ๅผทๅŠ›ใชใƒ„ใƒผใƒซใจใชใ‚Šใพใ™ใ€‚

3
3
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

@sakaki_developer's pickup articles

sakaki_developer

@sakaki_developer(sakaki)

I work as a developer at Accenture. All posts are my personal opinions and do not represent the opinions of any conmpany or organization I may be affiliated.

Today's trending articles

prum_hitomi

ๆŠ€่ก“ๅŠ›ใ ใ‘ใงใฏ้ธใฐใ‚Œใชใ„ใ€‚ๆœช็ตŒ้จ“ใ‚จใƒณใ‚ธใƒ‹ใ‚ขใŒ็พๅ ดใงๅทฎใ‚’ใคใ‘ใ‚‹ใ€Œๅฏพ่ฉฑใฎๆŠ€่ก“ใ€5้ธ

prum_hitomi

ใ€Œใใฎใ‚ณใƒผใƒ‰ใ€ๅ‹ๆ‰‹ใซไฝฟใฃใฆๅคงไธˆๅคซ๏ผŸใ€ITๅˆๅฟƒ่€…ใŒๆœ€ๅˆใซ็Ÿฅใ‚‹ในใโ€œ่‘—ไฝœๆจฉโ€ใฎ่ฉฑ

ใ€ŒAIๆ™‚ไปฃใฎใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚นใ€ไฝ•ใŒๅค‰ใ‚ใ‚‹๏ผŸใ€ใซใคใ„ใฆ่ชžใ‚ใ†๏ผ
KYoshiyama

ใƒ€ใƒƒใ‚ทใƒฅใƒœใƒผใƒ‰ใ‚’ไฝœใฃใŸใฎใซ่ชฐใ‚‚่ฆ‹ใฆใใ‚Œใชใ„ใฎใงใ€ใ‚ชใƒณใƒˆใƒญใ‚ธใƒผใซใคใ„ใฆ่€ƒใˆใฆใฟใŸ

Comments

No comments

Let's comment your feelings that are more than good

Being held Article posting campaign

3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address