Версия для печати темы
Форум программистов _ Delphi - Базы данных _ Delphi и Mssql
Автор: Arcangel 22:04:2008, 15:16
Посмотрел по форуму, ничего подобного ненашел, решил завести тему. НУ жна помощь в доработке уже существующей и почти написанной программы.
1. Есть файл MSExcel необходимо его открыть и вставить данные. Если кто может помочь по коду . Буду очень благодарен. Так как я сам с офисом работал мало.
2. Есть таблица на сервере MSSQL в которой храняться предметы каждой специальности и время отведенное для них. НЕобходимо при выборе студента и двойном клике по записи, показать его успеваемость и предметы со временем. Причем, ID_studenta, ID_Predmeta, Time, Ocenka, должны будут храниться в другой талбице, причем одна таблиу=ца успеваемости для всех спеиальностей.
Автор: SMitty 25:04:2008, 08:25
На первый вопрос можно ответить примерно так:
Код
procedure SaveExcelFile(filename: String;SG: TStringGrid);
var WorkBk : _WorkBook;
WorkSheet : _WorkSheet;
I, J, R, C : Integer;
IIndex : OleVariant;
TabGrid : Variant;
begin
IIndex := 1;
R := SG.RowCount;
C := SG.ColCount;
if FileExists(filename) then DeleteFile(filename);
TabGrid := VarArrayCreate([0,(R - 1),0,(C - 1)],VarOleStr);
I := 0;
repeat
for J := 0 to (C - 1) do
TabGrid[I,J] := SG.Cells[J,I];
Inc(I,1);
until I > (R - 1);
DataModule1.ExcelApplication1.Connect;
DataModule1.ExcelApplication1.WorkBooks.Add(xlWBatWorkSheet,0);
WorkBk := DataModule1.ExcelApplication1.WorkBooks.Item[IIndex];
WorkSheet := WorkBk.WorkSheets.Get_Item(1) as _WorkSheet;
Worksheet.Range['A1',Worksheet.Cells.Item[R,C]].Value := TabGrid;
WorkSheet.Name := 'from My Delphi Application';
Worksheet.Columns.HorizontalAlignment := xlLeft;
WorkSheet.Columns.ColumnWidth := 14;
WorkSheet.Range['A' + IntToStr(1),'A' + IntToStr(R)].ColumnWidth := 31;
DataModule1.ExcelApplication1.Visible[0] := False;
WorkBk.Close(True, filename, 0, 0);
DataModule1.ExcelApplication1.Disconnect;
TabGrid := Unassigned;
end;
А со вторым вопросом не очень понятно в чем проблема. Получить ID студента из первой таблицы? Или вытянуть из MSSQL данные по этому ID?
Автор: Arcangel 25:04:2008, 17:18
Спасибо за помощь по первой части. Теперь что касается второй, надо не просто получить ID студента, а этот ID вставить в талбицу в Поле id_studenta и перенести IDшники каждого из предметов данной специальности и соспоставить с ID студента. чтобы по запросу из делфи:
ADOQuery.SQL.Text:= 'select PREDM.Predmet, '''+d+'''.Kodspecialnosti from '''+d+''', PREDM,YSPEV where '''+d+'''.Kodspecialnosti=PREDM.Kodspecialnosti and PREDM.Id = YSPEV.id_predm and BAHK.Id = YSPEV.id_studenta' ;
'''+d+''' - в данном случает переменная через котрую происходит обращение к таблицам через форму.
По данному запросу должен быть осуществлен вывод успеваемости выбранного студента из таблицы специальности.
Автор: sax_ol 28:04:2008, 14:24
Цитата(Arcangel @ 25:04:2008 - 19:18)

ADOQuery.SQL.Text:= 'select PREDM.Predmet, '''+d+'''.Kodspecialnosti from '''+d+''', PREDM,YSPEV where '''+d+'''.Kodspecialnosti=PREDM.Kodspecialnosti and PREDM.Id = YSPEV.id_predm and BAHK.Id = YSPEV.id_studenta' ;
За такое надо пожизненный ецих с гвоздями.
Автор: Arcangel 29:04:2008, 08:12
Цитата(sax_ol @ 28:04:2008 - 19:24)

Цитата(Arcangel @ 25:04:2008 - 19:18)
ADOQuery.SQL.Text:= 'select PREDM.Predmet, '''+d+'''.Kodspecialnosti from '''+d+''', PREDM,YSPEV where '''+d+'''.Kodspecialnosti=PREDM.Kodspecialnosti and PREDM.Id = YSPEV.id_predm and BAHK.Id = YSPEV.id_studenta' ;
За такое надо пожизненный ецих с гвоздями.
За что именно?
Автор: sax_ol 29:04:2008, 08:45
Цитата(Arcangel @ 29:04:2008 - 10:12)

За что именно?
1- за ADOQuery
2 - за такую вот ужасную строку (и тут есть вопросы: зачем вы ее собираете, у вас что таких таблиц много? даже если собирать, то про существование функции Format в курсе?)
3 - за название переменны (ну это так - по большому счету)
PS: + 4 за незнание SQL
Автор: Arcangel 29:04:2008, 14:26
Цитата(sax_ol @ 29:04:2008 - 13:45)

1- за ADOQuery
1. А что тогда использовать? БЕз компонентов производить запрос на клиент -сервеную БД?
Цитата(sax_ol @ 29:04:2008 - 13:45)

2 - за такую вот ужасную строку (и тут есть вопросы: зачем вы ее собираете, у вас что таких таблиц много? даже если собирать, то про существование функции Format в курсе?)
2. Как я обычно говорю, критиковать может каждый. Для примера взял бы и написал запрос подходящий для сборки. Но только для 13 таблиц которые
1. Никак не привязаны и формируются запросо
2. Соответственно все действия с ними производяться аналогично не как с таблицами а как с результатами запроса.
Цитата(sax_ol @ 29:04:2008 - 13:45)

3 - за название переменны (ну это так - по большому счету)
3. Каждый программирует по своему кому то переменные ти па "tyktykmoidrug" мало а кому то "d" вполне хватает чтобы машина обработала и выполнила запрос.
Автор: sax_ol 29:04:2008, 15:52
Цитата(Arcangel @ 29:04:2008 - 16:26)

1. А что тогда использовать?
ADODataSet, ADOCommand
Цитата(Arcangel @ 29:04:2008 - 16:26)

Для примера взял бы и написал запрос подходящий для сборки. Но только для 13 таблиц которые
А тут подробнее, что такое "для сборки", откуда взялись 13, что там и как несвязано ..
Цитата(Arcangel @ 29:04:2008 - 16:26)

Соответственно все действия с ними производяться аналогично не как с таблицами а как с результатами запроса.
Вас не удивлю если скажу что работая с SQL (*в этом смысле), всегда (ну или почти) работают с результатами запросов.
Цитата(Arcangel @ 29:04:2008 - 16:26)

Каждый программирует по своему
Больше никогда так не говорите, программировать надо так как надо, а так как не надо - программировать не надо.

ну вот разберем ваш запрос:
select PREDM.Predmet, '''+d+'''.Kodspecialnosti from '''+d+''', PREDM,YSPEV where '''+d+'''.Kodspecialnosti=PREDM.Kodspecialnosti and PREDM.Id = YSPEV.id_predm and BAHK.Id = YSPEV.id_studenta'
a) скажите откуда тут BAHK появился (его во from нету и в помине)?
в) зачем делать так "select PREDM.Predmet, '''+d+'''.Kodspecialnosti" если логичнее было бы так : select PREDM.Predmet, PREDM.Kodspecialnosti, зачем выкрутасы такие?
c) почему бы не пользовать алиасы? ну вот например так: from '''+d+''' as d, PREDM as p, YSPEV as y - потом читать легче (хотя тут могут возразить).
d) как уже говорил, непонял про несвязи, но тут напрашивается применение joins, т.е. можно записать так:
FROM '''+d+''' as d
INNER JOIN PREDM as p ON p.Kodspecialnosti=d.Kodspecialnosti
INNER JOIN YSPEV as y ON y.id_predm=p.Id
правда я незнаю куда тут и как BAHK впихнуть, т.к. а)
е) в итоге имеем:
SELECT p.Predmet, p.Kodspecialnosti
FROM '''+d+''' AS d
INNER JOIN PREDM AS p ON p.Kodspecialnosti=d.Kodspecialnosti
INNER JOIN YSPEV AS y ON y.id_predm=p.Id
вам некажеться, что так поприятнее будет?
f) ну и применим Format
... := Format("SELECT p.Predmet, p.Kodspecialnosti FROM %s AS d INNER JOIN PREDM AS p ON p.Kodspecialnosti=d.Kodspecialnosti INNER JOIN YSPEV AS y ON y.id_predm=p.Id", [d]);
Видите как стало т.с. читабельнее?
и последнее на сколько я понял, d это таблица конкретной специальности, вопрос: зачем их раскинули по разным таблицам? или ошибаюсь?
Автор: Arcangel 29:04:2008, 17:25
нет не ошибаетесь, таблиц 13. Теперь по порядку попробую ответить на все выше перечисленное. с ВАНК я промахнулся, там должно быть '''+d+''. Проблема в том что тот запрос что я написал выполняется напрямую из программы клиента написанном в делфи. d - это не таблица а переменная которой в зависимости от выбора специальности присваивается соответствующая таблица. Поэтому если я напишу p.Kodspecialnosti=d.Kodspecialnosti язык делфи поймет это как имена таблиц и соответственно выдаст ошибку компиляции. По поводу
Цитата(sax_ol @ 29:04:2008 - 20:52)

в) зачем делать так "select PREDM.Predmet, '''+d+'''.Kodspecialnosti" если логичнее было бы так : select PREDM.Predmet, PREDM.Kodspecialnosti, зачем выкрутасы такие?
PREDM.Predmet это столбец талицы с предметами а вот PREDM.Kodspecialnosti он нам нужен косвено только для сверки, в какой таблице мы сейчас находимся если они совпадают то соответственно выводится список предметов этой специальности и поставляются оценки студента. INNER JOIN да можно использовать но в данном случае можно обойтись и без него. Под сборкой я подразумевал запрос по нескольким таблицам и вывод нужных столбцов. Говоря что каждый программирует по своему я имел ввиду что каждый программист использует переменные и компоненты с которыми он привык работать и которые ему удобны. По поводу ADODataSet и ADOCommand возможно они и удобные я не отрицаю но я привык уже к ADOOuery и мне намного быстрее написать что то через него чем через что то мне не известное тем более когда время поджимает.
Автор: sax_ol 29:04:2008, 18:02
Цитата(Arcangel @ 29:04:2008 - 19:25)

таблиц 13
Все-таки почему 13, почему не одна? У них структуры разные или тождественны?
Цитата(Arcangel @ 29:04:2008 - 19:25)

Проблема в том что тот запрос что я написал выполняется напрямую из программы клиента написанном в делфи. d - это не таблица а переменная которой в зависимости от выбора специальности присваивается соответствующая таблица. Поэтому если я напишу p.Kodspecialnosti=d.Kodspecialnosti язык делфи поймет это как имена таблиц и соответственно выдаст ошибку компиляции.
Ну и что, запросы компилятор не парсит, этим занимается соотв. провайдер. который вы используете, т.е. тот что прописан в строке подключения - ConnectionString, следовательно ничего язык делфи не выдаст, пока его не поросит этот самый провайтед. А при правильно составленном запросе у него и повода не будет. И в p.Kodspecialnosti=d.Kodspecialnosti уже не ваша переменная, а
алиас на таблицу. т.е. написав "FROM TABLE1
AS T" мы имеем полное право далее работать с "Т" как с таблицей. Тут его еще применил, дабы убрать повторения конкатенации строк, которая прям вопиит.

Цитата(Arcangel @ 29:04:2008 - 19:25)

INNER JOIN да можно использовать но в данном случае можно обойтись и без него
А вот тут все зависит от структуры, т.к. mssql server при соотв. условия может использовать данное обстоятельстао и тем самым повысить производительность, т.е. ваш запрос будет выполняться быстрее.
Цитата(Arcangel @ 29:04:2008 - 19:25)

Под сборкой я подразумевал запрос по нескольким таблицам и вывод нужных столбцов.
Ну я примерно так и понял. Только поймите для программы совершенно наплевать сколько таблиц или поля каких таблиц учавствуют в наборе данных.
Набор он и есть набор, хоть 13 там таблиц хоть 130, а хоть и вовсе их там нет, все равно набор останется набором ...
Цитата(Arcangel @ 29:04:2008 - 19:25)

каждый программист использует переменные и компоненты с которыми он привык работать и которые ему удобны.
Это вы пока так думаете, со временем ваш взгляд на это поменяется. как говорится "не вы первый"

Цитата(Arcangel @ 29:04:2008 - 19:25)

По поводу ADODataSet и ADOCommand возможно они и удобные
Дело не в удобстве. а в том что они т.с. правильные, а ADOQuery мягко говоря - не очень.
Автор: Arcangel 29:04:2008, 20:49
Цитата(sax_ol @ 29:04:2008 - 23:02)

Все-таки почему 13, почему не одна? У них структуры разные или тождественны?
Структуры тождественные, просто изначально не продумал структуру как следует и сделал 13, и под эти 13 всю структуру клиента поставил, а теперь если менять базу надо весь клиент переписывать снова, а времени нет уже.
С алиасами я честно говорю, работать пробовал и потм от них отказался, эти алиасы на таблицы по карйней мере на локальных БД, надо созавать на всех ПК изнова как базу переносим. А это марока лишняя, значит надо человеку кто этим будеит пользоваться еще и про создание алиасов обьяснять. Возможно и существует способ по созанию переносимых алиасов но я таких незнаю.
Автор: sax_ol 30:04:2008, 05:51
Да структуру надо продумывать и всегда ее корректировать, иначе от граблей не отбиться.
Цитата(Arcangel @ 29:04:2008 - 22:49)

С алиасами я честно говорю, работать пробовал и потм от них отказался, эти алиасы на таблицы по карйней мере на локальных БД, надо созавать на всех ПК изнова как базу переносим. А это марока лишняя, значит надо человеку кто этим будеит пользоваться еще и про создание алиасов обьяснять. Возможно и существует способ по созанию переносимых алиасов но я таких незнаю.
Не вы не поняли. Это не те что используют при работе с БДЕ компонентами. Тут это локальная подмена реального объекта (в пределах только лишь конкретного запроса). Ни на что, кроме как на сам запрос это больше не распространяется. Более того вы можете такое делать не только с таблицами, но также с полями и даже целыми наборами (пример: select
mytable.* from (select * from table where field1=data1)
as mytable where
mytable.field2=data2). Но на клиенте, т.е. на программу это не повлияет никак.
Автор: Arcangel 30:04:2008, 08:25
ок. спс за разьяснения попробую, может что и получиться, хотя я уже частично обошел запрос, реализовав через Edit'ы
спс за помощь.
Русская версия Invision Power Board (http://www.nulled.ws)
© Invision Power Services (http://www.nulled.ws)