Сортировка - это расположение строк в таблице в определенном порядке. Чаще всего необходимо сортировать строки по данным одного или нескольких столбцов.

Сортировку можно производить как по возрастанию, так и по убыванию.

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

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

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

Сортировку таблицы можно выполнять при работе во вкладке Главная или Макет .

Сортировка таблицы производится следующим образом:

Установите курсор в любую ячейку таблицы.

Нажмите кнопку Сортировка в группе Абзац вкладки Главная или в группе Данные вкладки Макет .

В окне Сортировка в открывающемся списке поля Сначала по выберите столбец, по данным которого будет выполняться сортировка таблицы. В списке поля Т ип можно выбрать тип данных, по которым сортируется таблица, но обычно Word это делает автоматически. Установите переключатель направления сортировки по возрастанию или по убыванию.

В окне Параметры сортировки установите флажок только столбцы

8.4. Вычисления в таблице

В таблицах Word можно выполнять несложные вычисления с использованием формул. Для этого:

Установите курсор в ячейку, в которой требуется получить результат вычисления.

Во вкладке Макет в группе Данные нажмите кнопку Формула . Если эта кнопка не отображается, щелкните по стрелке кнопки Данные и, после отображения кнопки, нажмите ее.

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

Рис. 8.6. Создание формулы в ячейке

В некоторых случаях формула в окне Формула может быть записана автоматически. Например, если ячейка находится ниже ячеек с числами, будет записана формула = SUM (ABOVE) , что означает суммирование всех вышерасположенных ячеек. Если ячейка находится правее ячеек с числами, будет записана формула = SUM (LEFT) , что означает суммирование всех слева расположенных ячеек. Если требуется именно такое действие, можно применить эти формулы. В противном случае поле следует очистить и ввести формулу самостоятельно.

Формула вставляется в ячейку таблицы как специальное поле. При изменении значений в вычисляемых ячейках результат не будет автоматически изменяться. Для пересчета следует выделить ячейку и нажать клавишу F9.

8.5. Размещение таблицы в документе

Установка режима обтекания текстом.

Вставленная в документ таблица по умолчанию размещается без обтекания текстом с выравниванием по левому полю страницы.

Для выравнивания таблицы по краям страницы достаточно ее выделить и воспользоваться кнопками группы Абзац вкладки Главная . При таком выравнивании таблицы режим обтекания текстом не изменяется.

Изменить режим обтекания и положение таблицы можно следующим образом:

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

Нажмите на левую кнопку мыши и перетащите маркер. В процессе перетаскивания граница таблицы будет отображаться пунктиром.

Можно точно настроить положение таблицы на странице документа. Для этого:

Установите курсор в любой ячейке таблицы.

Во вкладке Макет в группе Таблица нажмите кнопку Свойства .

Во вкладке Таблица окна Свойства таблицы в разделе Обтекание выберите режим В округ и нажмите кнопку Размещение .

В окне Размещение таблицы (рис. 8.7) в разделе По горизонтали в раскрывающемся списке относительно можно выбрать, относительно какого элемента страницы будет выравниваться таблица: колонки, поля или страницы, а в списке поля Положение можно выбрать расположение таблицы (Слева , Справа , От центра , Внутри , Снаружи ) или ввести с клавиатуры требуемое значение в сантиметрах. Аналогично можно указать размещение таблицы и по вертикали.

Рис. 8.7. Установка положения таблицы

Для отказа от режима обтекания таблицы текстом следует установить курсор в любой ячейке таблицы, во вкладке Макет в группе Таблица нажать кнопку Свойства , во вкладке Таблица окна Свойства таблицы в разделе Обтекание выбрать режим нет .

Перенос заголовков таблицы на следующую страницу.

При создании таблиц, размещаемых на нескольких страницах, необходимо, чтобы названия столбцов таблицы отображались и печатались на каждой странице документа. Для этого:

Установите курсор в первую строку таблицы или, если в качестве заголовков используется несколько первых строк, выделите их.

Во вкладке Макет в группе Данные нажмите кнопку Повторить строки заголовков .

Преобразование таблицы в текст.

Всю таблицу или ее фрагмент можно преобразовать в текст. Для этого:

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

Во вкладке Макет в группе Данные нажмите кнопку Преобразовать в текст .

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

Рис. 11.20. Преобразование таблицы в текст

Выбранный разделитель разделяет данные ячеек одной строки; независимо от выбранного разделителя разделителем строк таблицы является знак абзаца.

Достаточно часто пользователям интернет приходится сталкиваться с большим объемом информации, представленным в виде таблицы. Не менее часто требуется получить результаты в ином порядке, чем они представлены первоначально. Большинство web-мастеров решает эту проблему применением сортировки на сервере, для чего используется перезагрузка страницы. Действительно, серверные языки предоставляют гораздо больше возможностей отсортировать многомерный массив по определенному значению, чем скриптовые языки, выполняющиеся непосредственно на стороне клиента. Решение сортировать данные на стороне сервера вполне оправданно с точки зрения трудозатрат программиста, так как многие серверные языки имеют встроенные функции сортировки многомерных массивов, и поэтому не требуется вдумываться в алгоритмы сортировки, что-то изобретать или перестраивать алгоритм под свои нужды. Но все-таки такое решение не оправдано, если подходить к этой проблеме с точки зрения пользователя. Вначале посетителю сайта требуется дождаться достаточно длительной загрузки страницы, просмотреть результаты, нажать на кнопку "Отсортировать" и... опять дожидаться, пока сервер закончит работу и вернет результат. Такие множественные перезагрузки страницы никак не способствуют популярности сайта у посетителя. В конце-концов, устав дожидаться очередной загрузки страницы, или испугавшись лишнего траффика, он покинет сайт в поисках более лояльного к нему web-мастера. Решением данной проблемы, а именно эффективной сортировки данных и формирования результирующей таблицы, я и предлагаю заняться в этой статье. А в качестве примера данных будет выступать информация о книгах: дата написания, название книги и ее автор.

Начнем с функции fillArray, которая и будет эмулировать многомерный массив, а вернее создать класс-объект с членами - данными многомерного массива. Приведем ее код:

Листинг 1: 1 function fillArray(years, books, authors) { 2 authors = upCs(authors, " "); 3 authors = upCs(authors, "-"); 4 books = upCs(books, ""); 5 6 this.years = years; 7 this.yweight = weight(years); 8 this.books = books; 9 this.bweight = weight(books); 10 this.authors = authors; 11 this.aweight = weight(authors); 12 }

Разберем данные по строкам. Во второй строке вызывается функция upCs с параметром authors и пробелом в качестве второго параметра. Функция upCs создает заглавные буквы в начале строки и перед каждым вхождением второго аргумента. Эта функция была написана исключительно потому, что не все обрабатывают данные должным образом и вполне могут написать имя писателя, например, с маленькой буквы. Применение такой функции устраняет возможную ошибку программиста в заполнении массива данными, а также позволяет быть уверенным, что в функции сортировки не будет неверного сравнения заглавных букв со строчными. Впрочем, если вы уверены в том, что данные будут занесены верно, можете убрать вызовы этой функции:

Листинг 2: 1 function upCs(str, param) { 2 var tmpStr = str.substring(0, 1).toUpperCase() + str.substring(1); 3 if(!param) 4 return tmpStr; 5 var separator = tmpStr.indexOf(param); 6 var retStr = tmpStr; 7 if(separator != -1) 8 retStr = tmpStr.substring(0, separator); 9 10 while(separator != -1) { 11 tmpStr = tmpStr.substr(separator + 1, 1).toUpperCase() + tmpStr.substring(separator + 2); 12 separator = tmpStr.indexOf(param); 13 if(separator != -1) 14 retStr += param + tmpStr.substring(0, separator); 15 else 16 retStr += param + tmpStr; 17 } 18 19 return retStr; 20 }

Эта же функция, вызванная с пустым вторым аргументом, возвращает результат с заглавной буквой только в начале строки. Теперь обратимся к строке 7, листинга 1. Здесь вызывается функция weight, которая возвращает числовые значения каждого символа аргумента в виде массива. Для чего я ее написал? Дело в том, что коды символов русского алфавита в браузере идут последовательно, кроме кода символа буквы "ё". Код этого символа больше кодов символов остального алфавита, поэтому приходится присваивать такое "весовое" значение этому символу, которое соответствовало бы его позиции в алфавите. Вот код этой функции:

Листинг 3: 1 function weight(str) { 2 var retArray = new Array(); 3 4 for(var i = 0; i < str.length; i++) { 5 var tmp = str.charCodeAt(i); 6 if(tmp >= 1046 && tmp < 1078) 7 tmp++; 8 else if(tmp == 1025) 9 tmp = 1046; 10 else if(tmp >= 1078) 11 tmp++; 12 else if(tmp == 1105) 13 tmp = 1078; 14 retArray[ i ] = tmp; 15 } 16 17 return retArray; 18 }

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

Листинг 4: 1 var txt = ; 2 txt[ 0 ] = new fillArray("1959", "фрейд", "сартр жан-поль"); 3 txt[ 1 ] = new fillArray("1940", "подростки", "сэлинджер джером"); 4 txt[ 2 ] = new fillArray("1946", "пена дней", "виан борис"); 5 txt[ 3 ] = new fillArray("1948", "осадное положение", "камю альбер"); 6 txt[ 4 ] = new fillArray("1899", "об иноческой жизни", "рильке райнер мария"); 7 txt[ 5 ] = new fillArray("1849", "аннабель Ли", "по эдгар"); 8 txt[ 6 ] = new fillArray("1917", "дагон", "лавкрафт говард"); 9 txt[ 7 ] = new fillArray("1915", "процесс", "кафка франц"); 10 txt[ 8 ] = new fillArray("1989", "египет Рамсесов", "монтэ пьер"); 11 txt[ 9 ] = new fillArray("1932", "мастер и Маргарита", "булгаков михаил");

Обратить внимание стоит лишь на то, что года, когда были написаны книги, я передаю в функцию в качестве строкового параметра, а не числового. Делается это для того, чтобы не писать несколько функций сортировки.

Насколько быстр такой метод заполнения массива? На компьютере со средней производительностью загрузка 1000 элементов происходит за 450 - 800 миллисекунд. Но поскольку пользователь будет получать массив такого размера не сразу, а по частям, и размер этих частей будет сильно зависеть от скорости его соединения с интернет, то время, затрачиваемое на создание элемента массива и определение весовых значений его данных, будет незаметно пользователю.

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

Листинг 5: 1 function quickSort(l, h, type) { 2 var low = l; 3 var high = h; 4 var rt = eval("txt[ " + Math.round((l + h) / 2) + " ]"); 5 var middle = new fillArray(rt.years, rt.books, rt.authors); 6 7 do { 8 9 while(isLow(eval("txt[ " + low + " ]"), middle, type)) 10 low++; 11 12 while(isLow(middle, eval("txt[ " + high + " ]"), type)) 13 high--; 14 15 if(low = 1046 && tmp < 1078) tmp++; else if(tmp == 1025) tmp = 1046; else if(tmp >= 1078) tmp++; else if(tmp == 1105) tmp = 1078; retArray[ i ] = tmp; } return retArray; } function fillArray(years, books, authors) { authors = upCs(authors, " "); authors = upCs(authors, "-"); books = upCs(books, ""); this.years = years; this.yweight = weight(years); this.books = books; this.bweight = weight(books); this.authors = authors; this.aweight = weight(authors); } function isLow(low, high, type) { var len1 = low[ type ].length; var len2 = high[ type ].length; var length = len1 < len2 ? len1: len2; for(var i = 0; i < length; i++) { var str1 = low[ type ][ i ]; var str2 = high[ type ][ i ]; if(str1 < str2) return true; if(str1 > str2) return false; } if(len1 < len2) return true; return false; } function quickSort(l, h, type) { var low = l; var high = h; var rt = eval("txt[ " + Math.round((l + h) / 2) + " ]"); var middle = new fillArray(rt.years, rt.books, rt.authors); do { while(isLow(eval("txt[ " + low + " ]"), middle, type)) low++; while(isLow(middle, eval("txt[ " + high + " ]"), type)) high--; if(low " : "