Объединение файлов .csv в запросе для извлечения его данных из Excel через соединение UDF и ADODB - PullRequest
0 голосов
/ 16 января 2019

Моя цель - запустить некоторый код в vba и вызвать функцию из ячейки Excel, чтобы извлечь некоторые данные из закрытого файла .csv или .xlsx.

Это можно сделать несколькими способами, но все, что я пробовал, имеет важное ограничение.

Я начинаю с очень большого .csv файла. Очень большой - около 4000 строк и более 1000 столбцов.

Первая попытка:

Сохраните .csv на листе Excel и используйте ExecuteExcel4Macro для извлечения данных. Это прекрасно работает при запуске Sub и даже при запуске Function. Но, к сожалению, вы не можете использовать ExecuteExcel4Macro и вызывать его из ячейки Excel. Первая попытка сделана.

Вторая попытка

Используйте ADODB Connection и выполните запрос непосредственно из файла .csv или из сохраненного файла .xlsx. Это можно использовать из ячейки, но, к удивлению, к удивлению, она имеет ограничение в 255 столбцов или полей. Я имею в виду, когда вы запускаете запрос и пытаетесь прочитать поле, расположенное в столбце с номером больше 255, функция ничего не делает. Вторая попытка сделана.

Третья (и последняя (сейчас)) попытка. Нужна ваша помощь здесь!

Хорошо, я мог бы разделить исходную таблицу, в которой слишком много полей, на несколько таблиц, содержащих максимум 255 полей в каждой.

Примечание: первый столбец содержит идентификаторы фирм, банков или чего-либо еще. Остальные поля называются x1, x2, ... x1050 и соответствуют полям финансовой отчетности, поэтому все они числовые и полезны для анализа.

Если я разделю большой стол на разные, аспект будет выглядеть так:

Table 1:
Name     x1     x2     x5    x6    x15...
myName1  15025  1546   6546  548   98663
myName2  867486 4684   68786 876   68997
myName3  87663  43397  87987 457   -4554
etc.

...

Table n:
Name     x928     x929     x940    x1005    x1250
myName1  765454   541546   76546   74548    18663
myName2  6564     544684   686     41876    58997
myName3  4687     64397    9887    879457   8554

Я могу сделать это, запустив vba перед сохранением файлов, поэтому теперь у меня есть n .csv файлы. Дело в том, что я хочу, чтобы формула вызывалась из такой клетки:

=GetData(path,file,name,operations)

Я имею в виду, пользователь хочет найти name в file и сделать несколько operations с «всеми» доступными полями, от 1 до 1250.

Предположим, что первая разделенная таблица переходит от поля x1 к полю x250. Вторая будет иметь размер от x251 до x500 и т. Д. У всех таблиц, конечно, будет первый столбец с полем names, и все таблицы будут иметь одинаковое количество строк (не одинаковое количество столбцов, как не все поля х существуют).

Но, что важно, operations, вызываемый пользователем, может выглядеть так:

"x3"                      --> User requests only one field.
"x5+x150"                 --> User requests the sum of two fields that would be in the same table (as the x150 field is not greater than x250 field)
"x452+x535-x900+x1200-x1" --> User requests operations with many fields that would be kept in different files. 

Когда пользователь запрашивает только поле, я могу написать небольшую подпрограмму в начале функции, чтобы сообщить функции, в которой .csv file хранится это поле, например:

if singleField<=250 then 
  fileToLookAt="SplittedCSV_1"
end if 
if singleField>250 and singleField<=500 then 
  fileToLookAt="SplittedCSV_2"
end if 

Затем, используя провайдера ADODB Connection и Microsoft.Jet.OLEDB.4.0, я бы запустил запрос как:

MyQuery = "SELECT x" & singleField & " AS MyData FROM [" & fileToLookAt & ".csv] WHERE Name='" & name & "'"

Но что происходит, когда пользователь хочет, чтобы операция с полями x была сохранена во всех разных файлах, как в третьем примере, который я привел? Мне бы пришлось «объединить» все таблицы, используя поле Name в качестве ключа для объединения.

Как бы вы поступили? Является ли объединение таблиц в Select лучшим вариантом? Как бы Select было бы?

Я имею в виду, что запрос будет выглядеть так:

MyQuery = "SELECT x452+x535-x900+x1200-x1 AS MyData FROM [" & MergedTable & ".csv] WHERE Name='" & name & "'"

Большое спасибо за ваше время.

1 Ответ

0 голосов
/ 16 января 2019

Вы можете поместить данные в mdb-файл, используя ado, и обойти ограничение в 256 столбцов. Однако использование UDF для извлечения данных непосредственно из любого внешнего источника данных будет очень медленным, если у вас их больше, чем несколько. Я бы создал класс для хранения данных с помощью метода load, вызываемого при открытии электронной таблицы, и чтобы ваши функции запрашивали объект. Таким образом, ваш метод загрузки принимает ваш CSV в качестве потока данных и заполняет дисконнектированный набор записей ado, определенный как статическая переменная, а затем вы определяете метод getdata, который возвращает желаемое значение на основе переданных ему параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...