Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Ближайший невыходной
 
 автор: Дядя Федор   (01.10.2010 в 17:04)   личное сообщение
 
 

Задача.
Есть табл TblTabCal
DataTabCAl-date
BlnDAy - boolean (true-work day)

Делаю ф-ю firstworkday(d as date) as date
Результатом д.б. первый невыходной день в том же месяце , что и d (d - всегда выходной (проверяется ранее)).
Предпочтительнее раньше.
Подчеркну - выходной в т.ч. и праздники, а не только сб,вс.

Будут ли оригинальные идеи, кроме брожения туда-сюда по рекордсету?

  Ответить  
 
 автор: Дядя Федор   (01.10.2010 в 17:25)   личное сообщение
 
 

Самое короткое решение пока такое (пример для 5 мая)

If (Month(DMax("[DataTabCal]", "[TblTabCal]", "[BlnDay] = True AND [DataTabCal] < #05/01/2010#")) = 5) Then
    MsgBox DMax("[DataTabCal]", "[TblTabCal]", "[BlnDay] = True AND [DataTabCal] < #05/01/2010#")
Else
    MsgBox DMin("[DataTabCal]", "[TblTabCal]", "[BlnDay] = True AND [DataTabCal] > #05/01/2010#")
End If

Автор-Елена Дувалина.

  Ответить  
 
 автор: kot_k_k   (01.10.2010 в 17:31)   личное сообщение
 
 

вопрос в тему дабы не плодить - есть ли возможность формулой подсчитать банковские дни между двумя датами, или кол-во воскресений (суббот) между двумя датами????

  Ответить  
 
 автор: Дядя Федор   (04.10.2010 в 14:31)   личное сообщение
 
 

Легко.

Аргументы: dtDate1 - начальная дата, dtDate2 - конечная дата, bUseHolidays - True - использовать таблицу праздников False - не использовать таблицу праздников 
Назначение: Расчет количества рабочих дней выпадающих на заданный временной интервал 
Возвращает: Количество рабочих дней. 

Public Function WorkDays(ByVal dtDate1 As Date, ByVal dtDate2 As Variant, Optional ByVal bUseHolidays As Variant) As Long 
Dim l As Long, wd1 As Integer, wd2 As Integer 
Dim wd As Long 

If IsMissing(bUseHolidays) Then 
    bUseHolidays = False 
End If 
l = DateDiff("d", dtDate1, dtDate2, vbMonday) 
wd1 = WeekDay(dtDate1, vbMonday) 
wd2 = WeekDay(dtDate2, vbMonday) 
wd = l - ((l + wd1 + (7 - wd2)) / 7&) * 2& + 1& 
If wd1 = 7 Then 
    wd = wd + 1 
End If 
If wd2 <= 5 Then 
    wd = wd + 2 
ElseIf wd2 = 6 Then 
    wd = wd + 1 
End If 
If bUseHolidays Then 
    wd = wd - DCount("*", "tblHolidays", "[Holiday] Between #" & _ 
    Format(dtDate1, "yyyy mm dd") & "# And #" & _ 
    Format(dtDate2, "yyyy mm dd") & "#") 
End If 
WorkDays = wd 
End Function 

Примечания: 
Суббота и воскресенье считаются нерабочими днями. 
Таблица праздников в данном примере называется "tblHolidays" и содержит одно поле "Holiday" типа Date/Time . В эту таблицу заносятся даты праздников которые не попадают на субботу и воскресенье. 
Автор: из справочника ProgramAdvices 

  Ответить  
 
 автор: Lukas   (01.10.2010 в 18:41)   личное сообщение
12 Кб.
 
 

О как, попробуй:

Public Function GetWorkDay(CurDay As Date) As Date
    Const SQLDATE As String = "\#mm\/dd\/yyyy\#"
    Dim strSQL As String
    Dim strOnDay As String
    
    strOnDay = Format$(CurDay, SQLDATE)
    strSQL = "SELECT TOP 1 Q1.CurDay " _
            & "FROM (" _
                & "SELECT OnDay + Shift AS CurDay, Shift " _
                & "FROM tblShift " _
                & "WHERE Month(OnDay + Shift) = Month(OnDay)" _
            & ") AS Q1 " _
            & "LEFT JOIN tblTabCal ON Q1.CurDay = tblTabCal.DataTabCal " _
            & "WHERE (Weekday(Q1.CurDay, 2) Between 1 And 5 AND tblTabCal.BlnDay Is Null) OR (tblTabCal.BlnDay) " _
            & "ORDER BY Abs(Q1.Shift), Q1.Shift;"
    strSQL = Replace(strSQL, "OnDay", strOnDay)
    GetWorkDay = CurrentProject.Connection.Execute(strSQL)(0)
End Function

+доп табличка =>
Дата входного параметра просто откидывает.
Если не нужно, что бы откидывало, добавить в спец табличку 0.

  Ответить  
 
 автор: Explorer   (01.10.2010 в 20:17)   личное сообщение
 
 

Лукас, ты что курил?

по ТЗ просто первый рабочий день определенного месяца

  Ответить  
 
 автор: Lukas   (02.10.2010 в 00:35)   личное сообщение
 
 

Голубого верблюдА!
Я понял так: ближайший рабочий день (назад-вперед) этого месяца, предпочтительно в меньшую сторону, при одинаковой разнице.
Так пенсию на почте выдают.

  Ответить  
 
 автор: Lukas   (02.10.2010 в 00:57)   личное сообщение
 
 

Правда, я считал что там таблица исключений, а там, похоже, все дни подряд.
Ну обкурился малость.

  Ответить  
 
 автор: Дядя Федор   (04.10.2010 в 08:07)   личное сообщение
 
 

Точно так. Щас вернулся на работу. Покумекаю. Спасибо всем за ответы.

  Ответить  
 
 автор: Explorer   (01.10.2010 в 17:31)   личное сообщение
 
 

одним запросом делается - чего там еще искатьпо рекордсету

  Ответить  
 
 автор: Дядя Федор   (04.10.2010 в 14:42)   личное сообщение
 
 

Вот что получилось
'ищет первый рабочий день, ближайший к cd / сначала раньше, если нет - позже
'но обязательно в том же месяце


'ДВА ВАРИАНТА-  1:
Public Function Fworkday(cd As Date) As Date
Dim rst As DAO.Recordset
Const SQLDATE As String = "\#mm\/dd\/yyyy\#"
Dim strsql As String, strCrit As String, firstday As Date, lastday As Date
firstday = DateSerial(Year(cd), Month(cd), 1)
lastday = DateSerial(Year(cd), Month(cd) + 1, 0)
strCrit = "between " & Format$(firstday, SQLDATE) & " AND " & Format$(lastday, SQLDATE)
strsql = "select [DataTabCal],[BlnDay] from TblTabCal where DataTabCal " & strCrit
Set rst = CurrentDb.OpenRecordset(strsql)
With rst
 .FindFirst "[DataTabCal]=" & Format$(cd, SQLDATE)
 If !BlnDay Then
   Fworkday = cd
   Exit Function
 End If
End With
If (Month(DMax("[DataTabCal]", "[TblTabCal]", "[BlnDay] AND ([DataTabCal] < " & Format$(cd, SQLDATE) & ")"))) = Month(cd) Then
    Fworkday = DMax("[DataTabCal]", "[TblTabCal]", "[BlnDay] AND [DataTabCal] <" & Format$(cd, SQLDATE))
Else
    Fworkday = DMin("[DataTabCal]", "[TblTabCal]", "[BlnDay] AND [DataTabCal] >" & Format$(cd, SQLDATE))
End If
End Function
'2-й ВАРИАНТ
Public Function Fworkdays(cd As Date) As Date
'ищет пурвый рабочий день, ближайший к cd / сначала раньше, если нет - позже
'но обязательно в том же месяце
Dim rst As DAO.Recordset
Dim bb As Variant
Const SQLDATE As String = "\#mm\/dd\/yyyy\#"
Dim strsql As String, firstday As String, lastday As String
firstday = Format$(DateSerial(Year(cd), Month(cd), 1), SQLDATE)
lastday = Format$(DateSerial(Year(cd), Month(cd) + 1, 0), SQLDATE)
strsql = "select [DataTabCal],[BlnDay] from TblTabCal where DataTabCal " & _
"between " & firstday & " AND " & lastday
Set rst = CurrentDb.OpenRecordset(strsql)
With rst
 .FindFirst "[DataTabCal]=" & Format$(cd, SQLDATE)
 If !BlnDay Then
   Fworkdays = cd
   Exit Function
 Else
   bb = .Bookmark
   Do
     If !BlnDay Then
        Fworkdays = !DataTabCal
        Exit Function
     End If
     .MovePrevious
   Loop Until .BOF
  .Bookmark = bb
  Do
     If !BlnDay Then
        Fworkdays = !DataTabCal
        Exit Function
     End If
     .MoveNext
  Loop Until .EOF
 End If
End With
End Function


ВАРИАНТ 2 в 2 раза быстрее
Будет использоваться в запросах по построению плана выпуска

  Ответить  
 
 автор: osmor   (04.10.2010 в 14:56)   личное сообщение
 
 

либо я не понял задачу... либо одно из двух

SELECT TOP 1 DataTabCAl
FROM TblTabCal
WHERE Year([DataTabCAl])=Year([d]) AND BlnDAy=True AND Month([DataTabCAl])=Month([d])
ORDER BY DataTabCAl;

  Ответить  
 
 автор: Explorer   (04.10.2010 в 16:38)   личное сообщение
 
 

мы с тобой неправильно задачу поняли - не первая а ближайшая

если ближайших две то более раняя

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 08:11)   личное сообщение
 
 

В точку!

  Ответить  
 
 автор: osmor   (05.10.2010 в 12:19)   личное сообщение
 
 

тогда так
SELECT top 1 DataTabCAl
FROM TblTabCal
WHERE Year([DataTabCAl])=Year([d]) AND BlnDAy=True AND Month([DataTabCAl])=Month([d])
ORDER BY 31*(([DataTabCAl]-CDate([d]))>0)-Abs([DataTabCAl]-CDate([d])) DESC;

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 13:20)   личное сообщение
 
 

Это круто, но медленно
Вариант 2 - 3142
Вариант Osmor - 13723
На табл. из 2000 записей
Дело в том, что мне нужна функция, которая исп. в запросе, а не единичный вызов.
Функция от Osmor получилась такая


Public Function Fworkdayq(d As Date) As Date
Dim strsql As String
Dim rst As DAO.Recordset
strsql = _
"SELECT top 1 DataTabCAl FROM TblTabCal WHERE Year([DataTabCal]) = Year([d]) And BlnDay = True And Month([DataTabCal]) = Month([d]) " & _
"ORDER BY 31*(([DataTabCAl]-CDate([d]))>0)-Abs([DataTabCAl]-CDate([d])) DESC;"
strsql = Replace(strsql, "[d]", Format$(d, "\#mm\/dd\/yyyy\#"))
Set rst = CurrentDb.OpenRecordset(strsql)
Fworkdayq = rst.Fields(0)
Set rst = Nothing
End Function

  Ответить  
 
 автор: Explorer   (05.10.2010 в 13:30)   личное сообщение
 
 

отмечай True выходные а не рабочие :)

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 13:35)   личное сообщение
 
 


отмечай True выходные а не рабочие :)


Сие не в наших силах. Базе уже года 4 будет. Модули пишемс.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 13:53)   личное сообщение
 
 

а-а-а...

у меня просто всегда выходные галками

  Ответить  
 
 автор: osmor   (05.10.2010 в 14:37)   личное сообщение
 
 

Дело в том, что мне нужна функция, которая исп. в запросе, а не единичный вызов.


как раз этот запрос и можно вставить как источнеик значения поля в исходном запросе
например есть таблица где короме прочих полей есть поле с датой для которого нужно найти ближайший рабочий
таблица называется TblTWdate а поле INDate ТОгда результирующий запрос содержащий все поля и все записи из TblTWdate и поле с ближайшей рабочей датой для INDate в данной строке будет выглядеь так

SELECT TblTWdate.*, (SELECT TOP 1 TblTabCal.DataTabCAl
FROM TblTabCal
WHERE (((Year([DataTabCAl]))=Year(INDate)) AND ((TblTabCal.BlnDAy)=True) AND ((Month([DataTabCAl]))=Month([INDate])))
ORDER BY 31*(([DataTabCAl]-[INDate])>0)-Abs([DataTabCAl]-[INDate]) DESC;) AS firstwork
FROM TblTWdate;

поскольку поля даты то cdate ненужно

вечером домой приду - сваргаяню пример

  Ответить  
 
 автор: Lukas   (05.10.2010 в 14:48)   личное сообщение
 
 

...;...;
вряд-ли пропустит две "точка с запятой".

  Ответить  
 
 автор: osmor   (05.10.2010 в 14:53)   личное сообщение
 
 

вот ведь...
пойду найду кого нибуть с ACCESS и проверю :-)
все забыл уже... чего и не знал...

  Ответить  
 
 автор: Lukas   (05.10.2010 в 14:58)   личное сообщение
 
 

Да просто первая "точка с запятой" лишняя. Убрать нужно.
И условие не оптимальное КМК.

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 14:54)   личное сообщение
 
 

Это понятно, но по скорости он уступит "фрикциям" по рекордсету из варианта 2. Проверю сейчас, если не отвлекут.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 13:28)   личное сообщение
 
 


AND BlnDAy=True





SELECT TOP 1 tblCalendar.DateCal
FROM tblCalendar
WHERE (((Format([DateCal],"mm yyyy"))=Format([a],"mm yyyy")) AND ((tblCalendar.IsDayOff)=No))
ORDER BY Abs(DateDiff("d",[DateCal],[a])), tblCalendar.DateCal DESC;

  Ответить  
 
 автор: Lukas   (05.10.2010 в 13:46)   личное сообщение
 
 

А почему бы в условии не использовать преимущества индекса по полю [DateCal]? :)

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 14:01)   личное сообщение
 
 

вполне премлем мой вариант2. Гораздо большую задержку вызывает сборка текстовых полей-аналог
dsum.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 14:02)   личное сообщение
 
 

это просто запросы из подмышки на скорую руку

исходя из того, что нужен ближайший рабочий день, вперед-назад, желательно назад

ограничиться текущим месяцем это допусловие

ЗЫ

в общем случае если в году не 365 выходных то достаточно месяца - год в условии не нужен

  Ответить  
 
 автор: Lukas   (05.10.2010 в 14:26)   личное сообщение
 
 


...ограничиться текущим месяцем это допусловие...


При таком Order By, я бы так не сказал. :)
Чем меньше записей пропустит условие, тем меньше придется считать при сортировке.

WHERE DateCal Bettwen НачалоМесяца And КонецМесяца AND BlnDay

НачалоМесяца и КонецМесяца можно либо считать в запросе (если запрос сохраненный),
либо подставлять конкретные значения, если SQL строку собирать в коде.

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 15:04)   личное сообщение
 
 

Я придумал самый быстрый способ!!!!!!
Добавляем в TblTabCal поле FirstWork.
Прогоняем 1(!) раз запрос, который формирует FirstWork Для DAtaTabCal.
И все. Берем когда надо.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 15:38)   личное сообщение
 
 

дядя федор, сколько у тебя записей в той таблице?

в году всего 365 дней а горизонт оперативного планирования обычно дней 90-то

SELECT DateCal, NearestWDay([DateCal]) AS NextWorkDay
FROM tblCalendar


Public Function NearestWDay(aDate As Date) As Date
Dim strSQL As String
strSQL = "SELECT TOP 1 tblCalendar.DateCal FROM tblCalendar WHERE (((Month([DateCal])) = Month(" _
& Format(aDate, "\#mm\/dd\/yyyy\#") & ")) And ((tblCalendar.IsWorkDay) = Yes))" _
"ORDER BY Abs(DateDiff('d',[DateCal]," _
& Format(aDate, "\#mm\/dd\/yyyy\#") & ")), tblCalendar.DateCal;"
NearestWDay = CurrentProject.Connection.Execute(strSQL)(0)
End Function

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 16:24)   личное сообщение
 
 

Точно-горизонт 30-90 дн. (мес,квартал). Щас и эту ф-ю проверю

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 16:46)   личное сообщение
 
 

Проверил.
Результат 17483 (см.выше сравнение), плюс к тому - ищет СЛЕДУЮЩИЙ раб.день.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 17:04)   личное сообщение
89 Кб.
 
 

я особо не тестировал, времени нет.

но у меня выдает предыдущий а не следующий ==>>

если у тебя горизонт планирования 90 дней зачем проверяшь на таблице в 2000 записей?

какое значение имеет скорость выполнения такого запроса?

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 17:30)   личное сообщение
 
 

2000 - просто для теста. Запрос с этой функцией - основа отчета, который весьма динамично меняется(пользователь из упр.формы задает разные условия и т.п.).
А 2000, вернее около того - это ТblTabCal. Где как ни на ней проверить....

  Ответить  
 
 автор: Дядя Федор   (05.10.2010 в 17:33)   личное сообщение
 
 

Debug.Print NearestWDay(Date), NearestWDay(Date + 5), NearestWDay("1/1/2010")
05.10.2010 11.10.2010 01.01.2010

  Ответить  
 
 автор: Explorer   (05.10.2010 в 17:43)   личное сообщение
 
 

это чего за тест такой?

  Ответить  
 
 автор: Lukas   (05.10.2010 в 18:19)   личное сообщение
34 Кб.
 
 

Магистр,
ну хоть вы меня поддержите, а то они меня не слушають.
Испытуемые там =>
Результаты тестов:

Function      CalcDate      WorkDate      Time
==============================================
NearestWDay   01.01.2010    06.01.2010     839 
GetWorkDay2   01.01.2010    06.01.2010     213 
NearestWDay   02.01.2010    06.01.2010     691 
GetWorkDay2   02.01.2010    06.01.2010     212 
NearestWDay   03.01.2010    06.01.2010     738 
GetWorkDay2   03.01.2010    06.01.2010     210 
NearestWDay   04.01.2010    06.01.2010     695 
GetWorkDay2   04.01.2010    06.01.2010     214 
NearestWDay   05.01.2010    06.01.2010     691 
GetWorkDay2   05.01.2010    06.01.2010     210 
NearestWDay   06.01.2010    06.01.2010     698 
GetWorkDay2   06.01.2010    06.01.2010     221 
NearestWDay   07.01.2010    06.01.2010     690 
GetWorkDay2   07.01.2010    06.01.2010     209 
NearestWDay   08.01.2010    08.01.2010     700 
GetWorkDay2   08.01.2010    08.01.2010     217 
NearestWDay   09.01.2010    08.01.2010     797 
GetWorkDay2   09.01.2010    08.01.2010     207 
NearestWDay   10.01.2010    11.01.2010     686 
GetWorkDay2   10.01.2010    11.01.2010     213 
NearestWDay   11.01.2010    11.01.2010     689 
GetWorkDay2   11.01.2010    11.01.2010     213 
NearestWDay   12.01.2010    12.01.2010     768 
GetWorkDay2   12.01.2010    12.01.2010     206 
NearestWDay   13.01.2010    13.01.2010     684 
GetWorkDay2   13.01.2010    13.01.2010     207 
NearestWDay   14.01.2010    14.01.2010     791 
GetWorkDay2   14.01.2010    14.01.2010     222 
NearestWDay   15.01.2010    15.01.2010     697 
GetWorkDay2   15.01.2010    15.01.2010     222 
NearestWDay   16.01.2010    15.01.2010     742 
GetWorkDay2   16.01.2010    15.01.2010     211 
NearestWDay   17.01.2010    18.01.2010     759 
GetWorkDay2   17.01.2010    18.01.2010     211 
NearestWDay   18.01.2010    18.01.2010     782 
GetWorkDay2   18.01.2010    18.01.2010     268 
NearestWDay   19.01.2010    19.01.2010     726 
GetWorkDay2   19.01.2010    19.01.2010     242 
NearestWDay   20.01.2010    20.01.2010     764 
GetWorkDay2   20.01.2010    20.01.2010     207 
NearestWDay   21.01.2010    21.01.2010     733 
GetWorkDay2   21.01.2010    21.01.2010     218 
NearestWDay   22.01.2010    22.01.2010     753 
GetWorkDay2   22.01.2010    22.01.2010     206 
NearestWDay   23.01.2010    22.01.2010     724 
GetWorkDay2   23.01.2010    22.01.2010     219 
NearestWDay   24.01.2010    25.01.2010     688 
GetWorkDay2   24.01.2010    25.01.2010     231 
NearestWDay   25.01.2010    25.01.2010     690 
GetWorkDay2   25.01.2010    25.01.2010     207 
NearestWDay   26.01.2010    26.01.2010     691 
GetWorkDay2   26.01.2010    26.01.2010     208 
NearestWDay   27.01.2010    27.01.2010     685 
GetWorkDay2   27.01.2010    27.01.2010     206 
NearestWDay   28.01.2010    28.01.2010     718 
GetWorkDay2   28.01.2010    28.01.2010     211 
NearestWDay   29.01.2010    29.01.2010     763 
GetWorkDay2   29.01.2010    29.01.2010     245 
NearestWDay   30.01.2010    30.01.2010     750 
GetWorkDay2   30.01.2010    30.01.2010     209 
NearestWDay   31.01.2010    30.01.2010     691 
GetWorkDay2   31.01.2010    30.01.2010     210 

  Ответить  
 
 автор: Explorer   (05.10.2010 в 19:17)   личное сообщение
 
 


"ORDER BY Abs(" & strOnDay & "-DataTabCal), DataTabCal-" & strOnDay


Да

  Ответить  
 
 автор: Lukas   (05.10.2010 в 19:25)   личное сообщение
 
 

  Ответить  
 
 автор: Explorer   (05.10.2010 в 19:32)   личное сообщение
 
 

abs немного горчит... нет?

  Ответить  
 
 автор: Lukas   (05.10.2010 в 19:36)   личное сообщение
 
 

Да.
Можно Iif попробовать, возможно будет быстрее.

  Ответить  
 
 автор: Lukas   (05.10.2010 в 19:50)   личное сообщение
 
 

С такой сортировкой:

ORDER BY IIF(" & strOnDay & ">=DataTabCal," & strOnDay & " - DataTabCal, DataTabCal - " & strOnDay & "), DataTabCal-" & strOnDay

Даже на 5% быстрее.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 19:57)   личное сообщение
 
 


ORDER BY IIF


пля-я-я-я!!!

тут еще пошаманить можно...
-например что если от передаваемой даты заранее отнимать один день?

  Ответить  
 
 автор: Lukas   (05.10.2010 в 20:04)   личное сообщение
 
 

Не поможет в случае праздников + выходные, КМК.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 20:11)   личное сообщение
 
 

да это я сейчас другим занят - просто мысль мелькнула - как дать приоритет более ранней дате

т.е. может как-то загнать в одно условие DataTabCal и strOnDay без ИФов

  Ответить  
 
 автор: Lukas   (05.10.2010 в 20:20)   личное сообщение
 
 

Без IIF было-бы нарядней,
однако IIF есть джетовский и есть VBA-шный, а Abs - только VBA-шный.
В моей сортировке, похоже, используется джетовский,
потому как при всех его тормозах, он обогнал Abs.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 20:34)   личное сообщение
 
 

а просто умножить на -1?
----------------
тьху, фигня конечно :) там же и положительные значения
----------------
в общем на

"ORDER BY Abs(" & strOnDay & "-DataTabCal), DataTabCal-" & strOnDay

спокойно можно остановиться

  Ответить  
 
 автор: Lukas   (05.10.2010 в 21:02)   личное сообщение
 
 

А так:
(True/False)*2+1

Целиком:
"ORDER BY ((" & strOnDay & ">=DataTabCal)*2+1)*(DataTabCal-" & strOnDay & "), DataTabCal-" & strOnDay


Быстрее Abs, на уровне IIf.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 21:13)   личное сообщение
 
 


>=DataTabCal)*2+1



я такой трюк использую только если никто и никогда не увидит :)
хотя...

ЗЫ abs нормально - тут фишка в лаконичности ORDER BY - хорошо получилось
или нужно заходить вообще с другого края - оптимизации схемы и логики

  Ответить  
 
 автор: Lukas   (05.10.2010 в 21:14)   личное сообщение
 
 

Я не использую пока. :)

  Ответить  
 
 автор: Lukas   (05.10.2010 в 21:19)   личное сообщение
 
 


спокойно можно остановиться


Я думаю да, как на наиболее понятном. :)

Добавлено: не успеваю за вами, интернет медленный.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 21:27)   личное сообщение
 
 

было бы понятнее если бы второй ордер остался по дате - этакое контекстное документирование - но в ущерб скорости, существенно

вариант с двумя ордерами по разнице соединяет скорость лаконичность и читабельность

  Ответить  
 
 автор: Lukas   (05.10.2010 в 21:35)   личное сообщение
 
 

Я сейчас проверил, при второй сортировке по чистой дате, потери в скорости не заметил.
Так что можно и упростить.

  Ответить  
 
 автор: Explorer   (05.10.2010 в 21:45)   личное сообщение
 
 

но с двумя разницами красивее!!!

  Ответить  
 
 автор: Lukas   (05.10.2010 в 21:46)   личное сообщение
 
 

Да, вот.

  Ответить  
 
 автор: Дядя Федор   (06.10.2010 в 08:15)   личное сообщение
21 Кб.
 
 

Комп. 2,6 Ггц, 2Гб

Function      CalcDate      WorkDate      Time
==============================================
NearestWDay   01.01.2010    06.01.2010     441 
GetWorkDay2   01.01.2010    06.01.2010     147 
Fworkdays     01.01.2010    06.01.2010     113 
NearestWDay   02.01.2010    06.01.2010     440 
GetWorkDay2   02.01.2010    06.01.2010     147 
Fworkdays     02.01.2010    06.01.2010     113 
NearestWDay   03.01.2010    06.01.2010     441 
GetWorkDay2   03.01.2010    06.01.2010     146 
Fworkdays     03.01.2010    06.01.2010     112 
NearestWDay   04.01.2010    06.01.2010     442 
GetWorkDay2   04.01.2010    06.01.2010     144 
Fworkdays     04.01.2010    06.01.2010     110 
NearestWDay   05.01.2010    06.01.2010     441 
GetWorkDay2   05.01.2010    06.01.2010     143 
Fworkdays     05.01.2010    06.01.2010     112 
NearestWDay   06.01.2010    06.01.2010     440 
GetWorkDay2   06.01.2010    06.01.2010     145 
Fworkdays     06.01.2010    06.01.2010     107 
NearestWDay   07.01.2010    06.01.2010     442 
GetWorkDay2   07.01.2010    06.01.2010     145 
Fworkdays     07.01.2010    06.01.2010     109 
NearestWDay   08.01.2010    08.01.2010     455 
GetWorkDay2   08.01.2010    08.01.2010     146 
Fworkdays     08.01.2010    08.01.2010     108 
NearestWDay   09.01.2010    08.01.2010     442 
GetWorkDay2   09.01.2010    08.01.2010     145 
Fworkdays     09.01.2010    08.01.2010     109 
NearestWDay   10.01.2010    11.01.2010     441 
GetWorkDay2   10.01.2010    11.01.2010     144 
Fworkdays     10.01.2010    08.01.2010     111 
NearestWDay   11.01.2010    11.01.2010     439 
GetWorkDay2   11.01.2010    11.01.2010     145 
Fworkdays     11.01.2010    11.01.2010     107 
NearestWDay   12.01.2010    12.01.2010     440 
GetWorkDay2   12.01.2010    12.01.2010     144 
Fworkdays     12.01.2010    12.01.2010     108 
NearestWDay   13.01.2010    13.01.2010     440 
GetWorkDay2   13.01.2010    13.01.2010     144 
Fworkdays     13.01.2010    13.01.2010     108 
NearestWDay   14.01.2010    14.01.2010     440 
GetWorkDay2   14.01.2010    14.01.2010     145 
Fworkdays     14.01.2010    14.01.2010     109 
NearestWDay   15.01.2010    15.01.2010     440 
GetWorkDay2   15.01.2010    15.01.2010     144 
Fworkdays     15.01.2010    15.01.2010     108 
NearestWDay   16.01.2010    15.01.2010     441 
GetWorkDay2   16.01.2010    15.01.2010     144 
Fworkdays     16.01.2010    15.01.2010     109 
NearestWDay   17.01.2010    18.01.2010     442 
GetWorkDay2   17.01.2010    18.01.2010     143 
Fworkdays     17.01.2010    15.01.2010     111 
NearestWDay   18.01.2010    18.01.2010     439 
GetWorkDay2   18.01.2010    18.01.2010     145 
Fworkdays     18.01.2010    18.01.2010     110 
NearestWDay   19.01.2010    19.01.2010     442 
GetWorkDay2   19.01.2010    19.01.2010     146 
Fworkdays     19.01.2010    19.01.2010     109 
NearestWDay   20.01.2010    20.01.2010     443 
GetWorkDay2   20.01.2010    20.01.2010     146 
Fworkdays     20.01.2010    20.01.2010     109 
NearestWDay   21.01.2010    21.01.2010     442 
GetWorkDay2   21.01.2010    21.01.2010     145 
Fworkdays     21.01.2010    21.01.2010     110 
NearestWDay   22.01.2010    22.01.2010     443 
GetWorkDay2   22.01.2010    22.01.2010     146 
Fworkdays     22.01.2010    22.01.2010     111 
NearestWDay   23.01.2010    22.01.2010     442 
GetWorkDay2   23.01.2010    22.01.2010     147 
Fworkdays     23.01.2010    22.01.2010     111 
NearestWDay   24.01.2010    25.01.2010     442 
GetWorkDay2   24.01.2010    25.01.2010     146 
Fworkdays     24.01.2010    22.01.2010     111 
NearestWDay   25.01.2010    25.01.2010     442 
GetWorkDay2   25.01.2010    25.01.2010     148 
Fworkdays     25.01.2010    25.01.2010     109 
NearestWDay   26.01.2010    26.01.2010     444 
GetWorkDay2   26.01.2010    26.01.2010     147 
Fworkdays     26.01.2010    26.01.2010     109 
NearestWDay   27.01.2010    27.01.2010     443 
GetWorkDay2   27.01.2010    27.01.2010     146 
Fworkdays     27.01.2010    27.01.2010     109 
NearestWDay   28.01.2010    28.01.2010     443 
GetWorkDay2   28.01.2010    28.01.2010     145 
Fworkdays     28.01.2010    28.01.2010     110 
NearestWDay   29.01.2010    29.01.2010     442 
GetWorkDay2   29.01.2010    29.01.2010     146 
Fworkdays     29.01.2010    29.01.2010     110 
NearestWDay   30.01.2010    30.01.2010     442 
GetWorkDay2   30.01.2010    30.01.2010     146 
Fworkdays     30.01.2010    30.01.2010     110 
NearestWDay   31.01.2010    30.01.2010     443 
GetWorkDay2   31.01.2010    30.01.2010     147 
Fworkdays     31.01.2010    30.01.2010     110 

Ваши решения красивы. Но медленнее.
Что касается "горизонта", то дело не в днях(30-90), а в том, что в этот период в отчет попадает несколько сотен позиций (изделий) каждый с 2-мя-5-ью датами выпуска.
Но спасибо за обсуждение. Я многое почерпнул...

  Ответить  
 
 автор: Дядя Федор   (06.10.2010 в 08:22)   личное сообщение
80 Кб.
 
 

Здесь вопрос философский. Красивый запрос или рекордсет.
Но в копилочку знаний я Ваши изыскания добавил.
А вот для чего, собственно =>

  Ответить  
 
 автор: Explorer   (06.10.2010 в 09:13)   личное сообщение
 
 

в ТЗ ты просил решения отличные от блуждания по рекордсету...

  Ответить  
 
 автор: Дядя Федор   (06.10.2010 в 10:35)   личное сообщение
 
 

Да. И дискуссия получилась полезной. Спасибо всем.

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList