Сортируем по дате. Из серии "Размышления".

Автор PoliteInspire, 22 февраля 2011, 18:56

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

PoliteInspire

Всем доброго времени суток.
Данная тема была открыта по рекомендации raptor'a.
И сразу к сути дела:
Решил я сделать календарь игр баскетбольных команд. Оформил следующим образом - создал три страницы, назвал их "PR", "PRH" и "PRA". На странице "PRH" разместил результаты домашних игр команды (в данном случае возьмём Бостон), на странице "PRA" выездные результаты команды, а на странице "PR" общий календарь игр (Кому интересно скрины прилагаются).
Задача у нас стоит следующая - данные вбитые на странице "PRH" и "PRA" нам необходимо отобразить на странице "PR", отсортировав их по дате (всё видно в скринах).
Сначала было блеснула мысль воспользоваться функцией "IF", но после пяти минутного перебора и сравнения ячеек до меня дошло, что в случае с полным календарём (это 84 игры [кажется], а я взял для начала всего по четыре домашних и выездных) моя формула увеличивалась до невероятных размеров (и зачем это нам надо?).
Не долго думая я решил обратится к вышеупомянутому raptor'у и буквально на следующий день получил ответ. Он предложил выйти из ситуации при помощи следующего макроса: смотрите где-то здесь.

Sub PR01
  Dim oDoc As Object, oSheet As Object, oCell As Object, nn As Integer
 
  oDoc=ThisComponent
  oSheet1=oDoc.Sheets.getByName("PRH")
  oSheet2=oDoc.Sheets.getByName("PRA")
  oSheet3=oDoc.Sheets.getByName("PR")
 
  d0="06/10/2010" 'Самая ранняя дата из таблиц PRH и PRA
  dd0=DateValue(d0)
  dni=dd0

  STRMAX=MaxRow()+1

  DNIMAX=MaxDni(d0)

  n=3

Do
  For s=3 To STRMAX Step 3
  oCell1=oSheet1.getCellByposition(1,s) 
  dd=oCell1.getString()

If DateDiff("d",dd,dni)=0 Then
oCell1=oSheet1.getCellByposition(2,s+1) 
dataArray1 = oSheet1.getCellRangeByPosition(1,s-1,11,s+1).getDataArray
oSheet3.getCellRangeByPosition(1,n-1,11,n+1).setDataArray(dataArray1())
n=n+3
End If
Next s

  For s=3 To STRMAX Step 3
  oCell2=oSheet2.getCellByposition(1,s) 
  dd=oCell2.getString()

If DateDiff("d",dd,dni)=0 Then
oCell2=oSheet2.getCellByposition(2,s+1) 
dataArray2 = oSheet2.getCellRangeByPosition(1,s-1,11,s+1).getDataArray
oSheet3.getCellRangeByPosition(1,n-1,11,n+1).setDataArray(dataArray2())
n=n+3
End If
  Next s
  dni=DateAdd("d",1,dni)

Loop Until dni=DateAdd("d",DNIMAX,dd0)

'MsgBox "Таблица сделана"

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function MaxRow() As Integer
   oDocument = ThisComponent
   oSheets = oDocument.Sheets
   oSheet1 = oSheets.getByName("PRH")
   oSheet2 = oSheets.getByName("PRA")

   oCellCursor = oSheet1.createCursor
   oCellCursor.GotoEndOfUsedArea(False)
   nRow1 = oCellCursor.getRangeAddress().endRow
   
   oCellCursor = oSheet2.createCursor
   oCellCursor.GotoEndOfUsedArea(False)
   nRow2 = oCellCursor.getRangeAddress().endRow
   
   If nRow1>=nRow2 Then
  MaxRow=nRow1
   Else
  MaxRow=nRow2   
   End If
End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function MaxDni(d0) As Integer
   oDocument = ThisComponent
   oSheets = oDocument.Sheets
   oSheet1 = oSheets.getByName("PRH")
   oSheet2 = oSheets.getByName("PRA")

   oCellCursor = oSheet1.createCursor
   oCellCursor.GotoEndOfUsedArea(False)
   nRow1 = oCellCursor.getRangeAddress().endRow
'MsgBox nRow1
   oCell1=oSheet1.getCellByposition(1,nRow1-2)
   d1 = oCell1.getString()
'MsgBox d1
   oCellCursor = oSheet2.createCursor
   oCellCursor.GotoEndOfUsedArea(False)
   nRow2 = oCellCursor.getRangeAddress().endRow
'MsgBox nRow2
   oCell2=oSheet2.getCellByposition(1,nRow2-2)
   d2 = oCell2.getString()
'MsgBox d2

    If d1>=d2 Then
MaxDni=DateDiff("d",d0,d1)+1   
Else
MaxDni=DateDiff("d",d0,d2)+1
End If

End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Возможно вы скажите - задача решена, зачем открывать тему? Ну, во-первых кому не-будь это может пригодится, а во-вторых хотелось-бы услышать ваши предложения по решению данной задачи. Да и я весьма заинтересован в её исполнении с помощью функций, не прибегая к программированию?

Всем спасибо за потраченное время.

[вложение удалено Администратором]

dr.Faust

Это делать надо в Base.
Без программирования. Без функций.
Свобода информации - свобода личности!

mathnew

Если хочется в Calc, то можно и в Calc.

Но только надо делать наоборот, чтобы избежать сортировки по дате.

То есть, заполнять от руки таблицу на листе "PR" (общий календарь игр, и уже отсортирован по дате!).

А уж из этой таблицы отбирать данные для таблиц на листах "PRH" (домашние) и "PRA" (выездные).

mathnew

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

PoliteInspire

Вот сам файл. Кому интересно поломать голову.

mathnew
Ваше предложение заинтересовало. Можно подробнее?

[вложение удалено Администратором]

mathnew

Таблица общего календаря игр
+
дополнительный столбец с формулами
+
Автофильтр

[вложение удалено Администратором]

PoliteInspire

Отличненько.  :D Такая мысль меня тоже посещала, вот только не додумался выделить ещё один столбик. Покрутил фильтры и бросил затею. У вас вышло енто намного лучше.
Но! Я не уточнял, что выездные и домашние игры меня интересуют на отдельных страницах поскольку в дальнейшем планируется привязка к другому документу. То-бишь другой документ будет считывать информацию о проведённых играх и вести более обширную статистику. Вот как раз до меня и не дошло каким образом разместить фильтры на разных страницах.

raptor

#7
Если использовать способ mathnew, то разместить "Home" и "Away" на разных листах можно макросом, который в этом случае становится очень простым, т.к. не требуется сортировка по дате, да и Автофильтр уже не нужен.

Sub PR2AH
 Dim oDoc As Object, oSheet As Object, oCell As Object, nn As Integer
 
 oDoc=ThisComponent
 oSheet1=oDoc.Sheets.getByName("PRH")
 oSheet2=oDoc.Sheets.getByName("PRA")
 oSheet3=oDoc.Sheets.getByName("PR")

 n1=3
 n2=3
 STRMAX=MaxRowPR()+1

  For s=3 To STRMAX Step 3
  oCell3=oSheet3.getCellByposition(0,s)  
  dd=oCell3.getString()

If dd="Home" Then
dataArray3 = oSheet3.getCellRangeByPosition(1,s,11,s+3).getDataArray
oCell1=oSheet1.getCellByposition(1,n1)  
oSheet1.getCellRangeByPosition(1,n1,11,n1+3).setDataArray(dataArray3())
n1=n1+3
End If

   If dd="Away" Then
dataArray3 = oSheet3.getCellRangeByPosition(1,s,11,s+3).getDataArray
oCell2=oSheet2.getCellByposition(1,n2)  
oSheet2.getCellRangeByPosition(1,n2,11,n2+3).setDataArray(dataArray3())
n2=n2+3
End If

Next s

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function MaxRowPR() As Integer
  oDocument = ThisComponent
  oSheets = oDocument.Sheets
  oSheet = oSheets.getByName("PR")

  oCellCursor = oSheet.createCursor
  oCellCursor.GotoEndOfUsedArea(False)
  nRow = oCellCursor.getRangeAddress().endRow
 
  MaxRowPR=nRow
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''




[вложение удалено Администратором]

PoliteInspire

raptor
Тоже ничего. Но мне первый больше нравился - не надо было добавлять ещё один столбик.  ;D

raptor

Не проблема. Вот:
Sub PR2AH
  Dim oDoc As Object, oSheet As Object, oCell As Object, nn As Integer
 
  oDoc=ThisComponent
  oSheet1=oDoc.Sheets.getByName("PRH")
  oSheet2=oDoc.Sheets.getByName("PRA")
  oSheet3=oDoc.Sheets.getByName("PR")

  n1=3
  n2=3
  STRMAX=MaxRowPR()+1

  For s=3 To STRMAX Step 3
  oCell3=oSheet3.getCellByposition(2,s+1) 
  dd=oCell3.getString()

If dd="Boston Celtics" Then
dataArray3 = oSheet3.getCellRangeByPosition(1,s,11,s+3).getDataArray
oCell1=oSheet1.getCellByposition(1,n1) 
oSheet1.getCellRangeByPosition(1,n1,11,n1+3).setDataArray(dataArray3())
n1=n1+3
End If

    If dd <> "Boston Celtics" Then
dataArray3 = oSheet3.getCellRangeByPosition(1,s,11,s+3).getDataArray
oCell2=oSheet2.getCellByposition(1,n2) 
oSheet2.getCellRangeByPosition(1,n2,11,n2+3).setDataArray(dataArray3())
n2=n2+3
End If

Next s

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Function MaxRowPR() As Integer
   oDocument = ThisComponent
   oSheets = oDocument.Sheets
   oSheet = oSheets.getByName("PR")

   oCellCursor = oSheet.createCursor
   oCellCursor.GotoEndOfUsedArea(False)
   nRow = oCellCursor.getRangeAddress().endRow
 
   MaxRowPR=nRow
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


[вложение удалено Администратором]

PoliteInspire

raptor
Чёт он как-то обмельчал.
По-моему функций стало меньше, да и sub уменьшился вдвое.
Ща попробуем эффект.

raptor

Цитата: PoliteInspire от 25 февраля 2011, 11:46Чёт он как-то обмельчал.По-моему функций стало меньше, да и sub уменьшился вдвое.

Вот что значит правильно начать работу.
Цитата: mathnew от 23 февраля 2011, 06:45Но только надо делать наоборот

PoliteInspire

А это я гоню. Думал это первый переделан. Всё работает отлично. Ещё раз спасибо.

PoliteInspire

raptor
Смешно.
Вообще я думал так правильно - разделить на выездные, домашние, а потом уже формировать общий календарь. Мне казалось, что именно так строятся программы для ведения статистики. Хотя я могу и ошибаться.

raptor

Наверное, поэтому и говорят, что есть 3 степени лжи:
1. Просто ложь.
2. Наглая ложь.
3 Статистика.