Макрос копирования строки Calc в базу данных

Автор AlexWorkStream, 20 сентября 2017, 15:22

0 Пользователи и 1 гость просматривают эту тему.

AlexWorkStream

Добрый день. Интересует такой вопрос. Есть ли возможность посредством макроса, добавить определенную строку из calc во внешнюю базу данных .odb?

rami

Цитата: AlexWorkStream от 20 сентября 2017, 15:22
Добрый день. Интересует такой вопрос. Есть ли возможность посредством макроса, добавить определенную строку из calc во внешнюю базу данных .odb?
В каком смысле "внешняя база"? Если можете подключить базу к офису, то и добавить данные можно из любого источника макросом.

AlexWorkStream

Цитата: rami от 20 сентября 2017, 13:33добавить данные можно из любого источника макросом
Именно это и интересует, чтобы можно было добавить строку из calc в подключенную базу. Если можно, тыкните, пожалуйста, носом в пример такого макроса.

rami

Перед выполнением макроса всегда выделять нужный диапазон (можно любое число строк), столбцы соответствуют столбцам базы.


Sub InsertIntoBase
Dim oSheet, oRange, db, oStatement, i%, col1, col2, col3, oSql$

oSheet=ThisComponent.CurrentSelection.getSpreadsheet    'лист на котором выделен диапазон с данными
oRange=ThisComponent.CurrentSelection.getRangeAddress   'выделенный диапазон любое число строк
db=ConnectToDataBase("База")   'Имя подключаемой базы
oStatement=db.createStatement

For i=oRange.startRow To oRange.EndRow
col1=oSheet.getCellByPosition(0,i).String   'первый столбец текущей строки
col2=oSheet.getCellByPosition(1,i).Value    'второй столбец текущей строки
col3=oSheet.getCellByPosition(2,i).Value    'третий столбец текущей строки

'в запросе ниже заменить названия таблицы и полей
oSql="INSERT INTO ""Таблица"" " & "(""Поле1"",""Поле2"",""Поле3"") values " & _
"(" & col1 & "," & col2 & "," & col3 & ")"

oResult=oStatement.executeQuery(oSql)       'выполнение запроса
Next
DisconnectFromDataBase(db)     'отключаемся от базы
End Sub

'функция подключения к базе
Function ConnectToDataBase(dbName$) As Object
Dim dbContext As Object, oDataSource As Object
dbContext=createUnoService("com.sun.star.sdb.DatabaseContext")
oDataSource=dbContext.getByName(dbName)
ConnectToDataBase=oDataSource.GetConnection("","")
End Function

'процедура отключения
Sub DisconnectFromDataBase(db As Object)
db.close
db.dispose()
End Sub

AlexWorkStream


AlexWorkStream

Цитата: rami от 20 сентября 2017, 14:33col3=oSheet.getCellByPosition(2,i).Value    'третий столбец текущей строки
Столкнулся с проблемой. Допустим данная ячейка у меня в формате даты (дд.мм.гг), тогда макрос не работает. Я так понял надо поменять тип данных? Если не затруднит - подскажите пожалуйста.

rami

Цитата: AlexWorkStream от 20 сентября 2017, 14:58Допустим данная ячейка у меня в формате даты (дд.мм.гг), тогда макрос не работает. Я так понял надо поменять тип данных?
Попробуйте в запрос добавить одинарные кавычки так, чтобы они окружали дату (в примере выделил красным):
oSql="INSERT INTO ""Таблица"" " & "(""Поле1"",""Поле2"",""Поле3"") values " & _
   "(" & col1 & "," & col2 & ",'" & col3 & "')"

AlexWorkStream

#7
Цитата: rami от 29 сентября 2017, 09:08добавить одинарные кавычки
Добавил, но ничего не вышло... Не портирует именно из-за того, что в базе, данному столбцу, присвоен тип Date.

rami

Какой формат этого столбца в базе и в кальке (в кальке данные как число или текст)?

AlexWorkStream


economist

#10
Тогда насильно конвертируйте в дату:

col3=CDate(oSheet.getCellByPosition(2,i).Value)

Если будет 30.02.2017, 19-й век или 23-й  - будет ошибка, т.к. данные даты с т.зр. программы не существуют.

"Формат ячейки", грубо говоря, не влияет на его содержимое, а лишь на визуальное отображение. Правда есть одно но при интерактивном вводе. Все иные способы (импорт, вставка итп) - по-другому обрабатываются.

Для уверенного программирования дат - лучше всего представить что Calc, независимо от формата ячейки, всегда в ней хранит просто число, скажем 43007. Но если задать формат дата - будет отображаться 29.09.07. Если к этой ячейке прибавить 10 - получим 43007+10=43017 (09.10.17).

PS
Еще важно понимать в каком формате база данных хранит даты. Например SQLite всё хранит как текст, только любит чтобы он был в формате ГГГГ-ММ-ДД. Это совсем небольшая плата за самое высокое быстродействие с датами среди всех СУБД. Плюс у нее нет ограничений на времена и до Р.Х., и вплоть до 9999 года.      
 
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

rami

Цитата: AlexWorkStream от 29 сентября 2017, 09:19Не портирует именно из-за того, что в базе, данному столбцу, присвоен тип Date.
В базе сделайте тип "ЦЕЛОЕ [INTEGER]", а формат столбца (в базе) как дата.

AlexWorkStream

Цитата: rami от 29 сентября 2017, 10:56сделайте тип "ЦЕЛОЕ [INTEGER]"
Это работает, но вот только мне надо, чтобы в базе был тип "Дата", так как таблицы calc будут брать данные с базы, а при автоматическом обновлении данных, сбрасывается и тип столбцов calc.

AlexWorkStream

Цитата: economist от 29 сентября 2017, 10:20Тогда насильно конвертируйте в дату:

col3=CDate(oSheet.getCellByPosition(2,i).Value)

Не работает. Выдает это
Message: Unexpected token: . in statement [INSERT INTO "Задачи" ("ID","Примечания","КодЗадачи","ДатаКонца") values (14,10,10,19.02].

В values - все правильно, кроме последней даты - в таблице а меня так - 19.02.17

rami

Цитата: AlexWorkStream от 29 сентября 2017, 13:05
Цитата: rami от 29 сентября 2017, 10:56сделайте тип "ЦЕЛОЕ [INTEGER]"
Это работает, но вот только мне надо, чтобы в базе был тип "Дата", так как таблицы calc будут брать данные с базы, а при автоматическом обновлении данных, сбрасывается и тип столбцов calc.
После первого импорта из базы данных поставьте птичку "Сохранить форматирование" (меню "Данные" —> "Задать диапазон..."), после обновлений формат данных не будет слетать.