Гость
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ? / 19 сообщений из 19, страница 1 из 1
19.01.2018, 10:54
    #39586914
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
Делаю XSL-преобразование исходного XML для выгрузки его в Excel.
Использую стандартную XML-схему для этого:

Код: html
1.
2.
3.
4.
5.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel">
...
</xsl:stylesheet>



Вызываю Excel-функцию суммирования в формуле для ячейки вот таким образом:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel">
...
<xsl:template match="/">
<html xmlns="http://www.w3.org/TR/REC-html40"
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:x="urn:schemas-microsoft-com:office:excel" >
...
  <td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(A1:A5)</xsl:attribute>
     <!--xsl:attribute name="x:fmla">=SUM(R10C5:R<xsl:value-of select="9+count(ROW)-1"/>C5)</xsl:attribute-->
  </td>
...
</html>
</xsl:template>
</xsl:stylesheet>



и всё прекрасно работает.

но возникла необходимость использовать стиль адресации ячеек не буквено-цифровой A1, а цифровой R1C1.

Пытаюсь поменять:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel">
...
<xsl:template match="/">
<html xmlns="http://www.w3.org/TR/REC-html40"
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:x="urn:schemas-microsoft-com:office:excel" >
...
  <td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(R1C1:R5C1)</xsl:attribute>
  </td>
...
</html>
</xsl:template>
</xsl:stylesheet>



Не понимает. Эксель даёт ошибку.

Тогда в XSLT я меняю стиль адресации на R1C1 указывая:

Код: html
1.
2.
3.
...
<x:RefModeR1C1/>
...



и в Excel действительно меняется стиль адресации, но всё-равно выдаётся ошибка - не понимает формулу в формате R1C1.


Понимаю, что вопрос сложный, но вдруг кто сталкивался?
...
Рейтинг: 0 / 0
19.01.2018, 15:14
    #39587154
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
verterПонимаю, что вопрос сложный, но вдруг кто сталкивался?Создаете лист с формулой в Экселе, сохраняете в XML и смотрите, что получилось. Потом пишете соответствующую XSL. Если возникают трудности, тогда публикуете кусок целевого XML здесь
...
Рейтинг: 0 / 0
19.01.2018, 15:15
    #39587155
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
Здесь у Вас ошибка в том, что Вы атрибут определяете дважды
verter
Код: javascript
1.
2.
3.
<td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(R1C1:R5C1)</xsl:attribute>
  </td>
...
Рейтинг: 0 / 0
19.01.2018, 15:18
    #39587159
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
_Vasilisk_,
я, конечно, так и сделал - сохранил в XML лист Экселя с формулой в стиле R1C1 и с включённым цифровым режимом R1C1.
Но к моему удивлению в XML в формуле всё-равно стоял стиль A1.
...
Рейтинг: 0 / 0
19.01.2018, 15:27
    #39587167
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
_Vasilisk_Здесь у Вас ошибка в том, что Вы атрибут определяете дважды
verter
Код: javascript
1.
2.
3.
  <td class="xl788" style='border-left:none' x:num="" x:fmla="">
     <xsl:attribute name="x:fmla">=SUM(R1C1:R5C1)</xsl:attribute>
  </td>



да, убрал лишнее, но это не повлияло на результат - Ошибка в формуле ячейки.
...
Рейтинг: 0 / 0
19.01.2018, 15:59
    #39587195
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
verter_Vasilisk_Здесь у Вас ошибка в том, что Вы атрибут определяете дважды
пропущено...


да, убрал лишнее, но это не повлияло на результат - Ошибка в формуле ячейки.напишите формулу от руки, чтобы работала, сохраните и посмотрите отличия.
...
Рейтинг: 0 / 0
19.01.2018, 18:18
    #39587295
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
Antonariyverterпропущено...


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

делал уже так. всё-равно даже если сохраняю в R1C1, то в сохранённом XSLT получается A1.
...
Рейтинг: 0 / 0
19.01.2018, 22:48
    #39587359
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
verterесли сохраняю в R1C1, то в сохранённом XSLT получается A1.Значит R1C1 это вопрос чисто отображения. А внутри идет сохранение всегда в виде A1
...
Рейтинг: 0 / 0
20.01.2018, 15:47
    #39587533
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
_Vasilisk_verterесли сохраняю в R1C1, то в сохранённом XSLT получается A1.Значит R1C1 это вопрос чисто отображения. А внутри идет сохранение всегда в виде A1вообще-то нет, у меня были документы с обоими вариантами адресации. не понятно, почему у ТСа не работает. может версия офиса виновата?
...
Рейтинг: 0 / 0
23.01.2018, 10:42
    #39588914
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
решил сделать просто перечислением букв в шаблоне, вот так суммирую данные в ячейках A1:A5 и B1:B5:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/> 
    <xsl:if test="$cnum = 1"><xsl:value-of select="concat('A', '')"/></xsl:if>
    <xsl:if test="$cnum = 2"><xsl:value-of select="concat('B', '')"/></xsl:if>
    ...
</xsl:template>

<xsl:template name="printTotal">
  <xsl:param name="idx"/>  
    <xsl:if test="$idx > 0">
      <xsl:call-template name="printTotal">
        <xsl:with-param name="idx" select="$idx - 1"/>
      </xsl:call-template>    
      <td x:num=''>
        <xsl:attribute name="x:fmla">=SUM(<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>1:<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>5)</xsl:attribute>
      </td>
    </xsl:if>
</xsl:template>

<xsl:call-template name="printTotal">
  <xsl:with-param name="idx" select="2"/>      
</xsl:call-template>



и это работает. но надо распространить это решение на случай когда буквы в колонках закончатся и пойдут AA, AB, ...
а потом и BA, BB, ...
для этого я написал ещё вот такой шаблон:

Код: html
1.
2.
3.
4.
5.
6.
7.
<xsl:template name="printPreLetter">
  <xsl:param name="nmb"/>
    <xsl:if test="$nmb &lt;= 26"><xsl:value-of select="concat('', '')"/></xsl:if> 
    <xsl:if test="$nmb &gt; 26*1"><xsl:value-of select="concat('A', '')"/></xsl:if>
    <xsl:if test="$nmb &gt; 26*2"><xsl:value-of select="concat('B', '')"/></xsl:if>
    ...
</xsl:template>



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

Код: html
1.
2.
3.
4.
5.
6.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/> 
    <xsl:if test="$cnum = 1"><xsl:value-of select="concat(<xsl:call-template name="printPreLetter"><xsl:with-param name="nmb" select="$cnum"/></xsl:call-template>, 'A', '')"/></xsl:if>
    <xsl:if test="$cnum = 2"><xsl:value-of select="concat(<xsl:call-template name="printPreLetter"><xsl:with-param name="nmb" select="$cnum"/></xsl:call-template>, 'B', '')"/></xsl:if>
    ...
</xsl:template>



но получаю ошибку.
помогите, пожалуйста, новичку разобраться. Как правильно в этом случае вызвать шаблон?
...
Рейтинг: 0 / 0
23.01.2018, 16:10
    #39589296
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
Вопрос номер раз. Зачем вот эта порнография?
verter
Код: xml
1.
concat('B', '')

чем не угодило
Код: xml
1.
<xsl:value-of select="'A'"/>

?

Вопрос номер два. Судя по каскаду
Код: xml
1.
<xsl:if

о существовании
Код: xml
1.
<xsl:choose>

Вы не догадываетесь?

Зачем вызывать несколько раз
verter
Код: html
1.
<xsl:call-template name="printPreLetter"><xsl:with-param name="nmb" select="$cnum"/></xsl:call-template>


когда можно это сделать лишь однажды и сохранить значение в переменной мне тоже непонятно

Ну и вот эта запись - это да. Вы сами ее разберете через пару месяцев?
verter
Код: html
1.
<xsl:attribute name="x:fmla">=SUM(<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>1:<xsl:call-template name="printColumnLetter"><xsl:with-param name="cnum" select="$idx"/></xsl:call-template>5)</xsl:attribute>



Итого, с учетом всего, получаем
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
  <xsl:template name="printPreLetter">
    <xsl:param name="nmb"/>
    <xsl:choose>
      <xsl:when test="$nmb &lt;= 26"><xsl:value-of select="''"/></xsl:when> 
      <xsl:when test="$nmb &gt; 26*1"><xsl:value-of select="'A'"/></xsl:when>
      <xsl:when test="$nmb &gt; 26*2"><xsl:value-of select="'B'"/></xsl:when>
      ...
      <xsl:otherwise>
        ........
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="printColumnLetter">
    <xsl:param name="cnum"/>
    <xsl:variable name="preLetter">
      <xsl:call-template name="printPreLetter">
        <xsl:with-param name="nmb" select="$cnum"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$cnum = 1"><xsl:value-of select="concat($preLetter, 'A')"/></xsl:when>
      <xsl:when test="$cnum = 2"><xsl:value-of select="concat($preLetter, 'B')"/></xsl:when>
    </xsl:choose>
  </xsl:template>
  
  <td x:num=''>
    <xsl:attribute name="x:fmla">=SUM(
      <xsl:call-template name="printColumnLetter">
        <xsl:with-param name="cnum" select="$idx"/>
      </xsl:call-template>
      1:
      <xsl:call-template name="printColumnLetter">
        <xsl:with-param name="cnum" select="$idx"/>
      </xsl:call-template>
      5)
    </xsl:attribute>
  </td>


А теперь оптимизируем. Прежде всего, поднимем еще читабельность для блока <td x:num=''>
Код: xml
1.
2.
3.
4.
5.
6.
<xsl:variable name="column">
  <xsl:call-template name="printColumnLetter">
    <xsl:with-param name="cnum" select="$idx"/>
  </xsl:call-template>
</xsl:variable>
<td x:num='' x:fmla="{concat('SUM(', $column, '1:', $column, '5)')}"/>


Далее, все Ваши шаблоны - это всего-лишь попытка отобразить числа 1, 2, 3 на буквы A, B, C. Куча <xsl:if, это, конечно здорово, тем более при наличии буфера обмена, но почему бы не сделать все по человечески?
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<xsl:template name="numToLetter">
  <xsl:param name="num"/>
  <xsl:variable name="mask" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
  <xsl:value-of select="substring($mask, $num, 1)"/>
</xsl:template>

<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/>
  <xsl:variable name="preLetter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="$cnum div 26"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="letter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="$cnum mod 26"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:value-of select="concat($preLetter, $letter)"/>
</xsl:template>

...
Рейтинг: 0 / 0
23.01.2018, 16:56
    #39589349
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
_Vasilisk_,
огромное спасибо за помощь!

Я на все вопросы могу ответить так - у меня совсем мало опыта в этом деле, т.е. я новичёк, поэтому пишу пока плохой код, т.к. не знаю просто многих вещей. Про choose, конечно, знал, но посчитал, что с choose надо на 1 строку больше кода, но это же не суть.
Сейчас перепишу всё в соответствии с вашими исправлениями.
...
Рейтинг: 0 / 0
23.01.2018, 18:11
    #39589418
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
verterс choose надо на 1 строку больше кода, но это же не суть.С choose сравнения прекращаются при выполнении первого условия, а с набором if идет последовательный перебор всех вариантов
...
Рейтинг: 0 / 0
23.01.2018, 18:17
    #39589422
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
Ошибка. Вместо
_Vasilisk_
Код: xml
1.
<xsl:with-param name="num" select="$cnum div 26"/>

должно быть
Код: xml
1.
<xsl:with-param name="num" select="floor($cnum div 26)"/>
...
Рейтинг: 0 / 0
24.01.2018, 16:12
    #39590197
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
_Vasilisk_,
да, с floor я тоже сразу заметил, т.к. div - это не div, а просто деление.
кроме этого нужно 1 отнять ещё.
но есть и ещё одна ошибка 26 mod 26 = 0, а нам нужно 26, поэтому окончательный вариант будет такой:

Код: html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/>
  <xsl:variable name="preLetter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="floor(($cnum - 1) div 26)"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="letter">
    <xsl:variable name="res">
      <xsl:value-of select="$cnum mod 26"/>
    </xsl:variable> 
    <xsl:variable name="nmb">
      <xsl:choose>
        <xsl:when test="$res = 0"><xsl:value-of select="26"/></xsl:when>
        <xsl:otherwise><xsl:value-of select="$res"/></xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="$nmb"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:value-of select="concat($preLetter, $letter)"/>
</xsl:template>
...
Рейтинг: 0 / 0
24.01.2018, 16:14
    #39590199
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
_Vasilisk_verterс choose надо на 1 строку больше кода, но это же не суть.С choose сравнения прекращаются при выполнении первого условия, а с набором if идет последовательный перебор всех вариантов

это да, но я посчитал, что например

Код: html
1.
2.
<xsl:if test="$res = 0"><xsl:value-of select="26"/></xsl:if> 
<xsl:if test="$res &gt; 0"><xsl:value-of select="$res"/></xsl:if-->



короче чем:

Код: html
1.
2.
3.
4.
5.
  
<xsl:choose>
  <xsl:when test="$res = 0"><xsl:value-of select="26"/></xsl:when>
  <xsl:otherwise><xsl:value-of select="$res"/></xsl:otherwise>
</xsl:choose>
...
Рейтинг: 0 / 0
24.01.2018, 22:59
    #39590474
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
verterпоэтому окончательный вариант будет такой:Опять все усложнили
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
<xsl:template name="printColumnLetter">
  <xsl:param name="cnum"/>
  <xsl:variable name="local_num" select="$cnum - 1"/>
  <xsl:variable name="preLetter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="floor($local_num div 26)"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="letter">
    <xsl:call-template name="numToLetter">
      <xsl:with-param name="num" select="($local_num mod 26) + 1"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:value-of select="concat($preLetter, $letter)"/>
</xsl:template>
...
Рейтинг: 0 / 0
24.01.2018, 23:00
    #39590475
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
verterкороче чем:А написать в одну строчку еще короче. Только потом фиг, что разберешь
...
Рейтинг: 0 / 0
25.01.2018, 12:39
    #39590830
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ?
_Vasilisk_,
ещё раз большое спасибо!
я думаю эта ветка будет полезна и для других.
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Как в XSLT правильно использовать в XML-схеме MS Excel'я адресацию R1C1 ? / 19 сообщений из 19, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]