11

我有时会在 MS-Excel(v2007 和 v2003)中使用对称矩阵。

是否有一个选项可以帮助我将表达式从下三角形复制到上三角形?

它应该类似于复制和粘贴/转置,但这些功能通常仅适用于矩形区域。

在添加的图片中,您可以看到一个表达式示例,我必须通过链接矩阵上三角形中的对称值来复制该表达式。 对称表达式矩阵

4

9 回答 9

10

要获取适当单元格中的数字,我们可以使用OFFSET单元格地址作为表格的基础。请注意,如果在对角线上输入,公式将产生 *Circular Reference` 错误。该公式适用于对角线的两侧 - 您只需决定哪一个将保存数据,哪个将保存公式。

Offset 需要 Row 和 Column 来决定目标。通过从当前位置减去基本单元格的行和列,我们可以反转行和列,得到数据。

使用您的示例,使用B2中的表的来源,我们最终得到以下公式:

=OFFSET($B$2,COLUMN()-COLUMN($B$2),ROW()-ROW($B$2))

您可以将此公式复制到单元格中,并获得反射。现在你有了数字,你可以对反射进行任何你需要的计算。使用您的示例,这将使公式:

=10-OFFSET($B$2,COLUMN()-COLUMN($B$2),ROW()-ROW($B$2))

结果:

例子

使用INDEX使其不挥发会稍微改变公式。首先,我们需要引用整个表格,而不仅仅是顶部单元格。其次,我们需要将 1 添加到行/列计算中,因为它将第一个单元格称为 row/column ,而不是前面公式1的偏移量。0

=INDEX($B$2:$K$11,COLUMN()-COLUMN($B$2)+1,ROW()-ROW($B$2)+1)

您的 10-Cell 示例将变为:

=10-INDEX($B$2:$K$11,COLUMN()-COLUMN($B$2)+1,ROW()-ROW($B$2)+1)
于 2013-10-14T15:20:12.997 回答
3

正如上述答案之一所示,这可以通过使用 Excel 公式来完成。然而,我发现这是一个非常乏味的过程。特别是如果这是您需要定期做的事情。在这种情况下,VBA 可以为您节省大量时间。

以下代码将处理正方形选择并填充矩阵的其余部分,无论它是预填充的矩阵的下部还是上部。

Option Explicit

Sub FillSymetricMatrix()
    Dim i As Integer, j As Integer
    Dim SelRng As Range
    Dim FillArea As String
    Dim FRow As Integer
    Dim FCol As Integer

    Set SelRng = Selection
    FRow = SelRng.Rows(1).Row
    FCol = SelRng.Columns(1).Column

    'Returns information about which area to fill
    If ActiveSheet.Cells(FRow + SelRng.Rows.Count - 1, FCol).Value <> vbNullString Then       'Lower filled
        If ActiveSheet.Cells(FRow, FCol + SelRng.Columns.Count - 1).Value = vbNullString Then 'Upper empty
            FillArea = "Upper"
        Else
            FillArea = "Error"
        End If
    Else
        If ActiveSheet.Cells(FRow, FCol + SelRng.Columns.Count - 1).Value <> vbNullString Then 'Upper filled
            FillArea = "Lower"
        Else
            FillArea = "Error"
        End If

    End If

    'Determines if the selection is square
    If SelRng.Rows.Count <> SelRng.Columns.Count Then FillArea = "Error"


    'Fills empty area of the square (symetric) matrix
    Select Case FillArea
        Case Is = "Upper"
            For i = 0 To SelRng.Rows.Count - 1 Step 1
                For j = 0 To SelRng.Columns.Count - 1 Step 1
                    If i <= j Then ActiveSheet.Cells(i + FRow, j + FCol).Value = ActiveSheet.Cells(j + FRow, i + FCol).Value
                Next j
            Next i

        Case Is = "Lower"
            For i = 0 To SelRng.Rows.Count - 1 Step 1
                For j = 0 To SelRng.Columns.Count - 1 Step 1
                    If i <= j Then ActiveSheet.Cells(j + FRow, i + FCol).Value = ActiveSheet.Cells(i + FRow, j + FCol).Value
                Next j
            Next i

        Case Else
            MsgBox "The procedure cannot be performed on the current selection!"
    End Select
End Sub
于 2013-10-14T15:29:15.997 回答
2

我猜你需要的是一个返回方阵的“对角线”值的函数,例如任何X(j,k)返回X(k,j)

试试这个:

Function DIAGONAL(Arg As Range, Reference As Range) As Variant
Dim MyRow As Long, MyCol As Long

    If Reference.Rows.Count <> Reference.Columns.Count Then
        DIAGONAL = CVErr(xlErrRef)
    Else
        MyRow = Arg.Row - Reference.Row + 1
        MyCol = Arg.Column - Reference.Column + 1
        If MyRow < 1 Or MyCol < 1 Or MyRow > Reference.Rows.Count Or MyCol > Reference.Columns.Count Then
            DIAGONAL = CVErr(xlErrNA)
        Else
            DIAGONAL = Reference(MyCol, MyRow)
        End If
    End If

End Function

一旦你在 VBA 中输入了这个函数,你就可以在你的方阵内部或外部使用它......你只需要确保你的参数(参数:Arg)在矩阵(参数:参考)内......或者你得到一个#N/A 错误。或者,如果矩阵不是正方形,则会出现 #REF 错误。

因此,在您的示例中,您将输入 B4:=10-DIAGONAL(B4,$B$2:$K$11)并将其复制到整个下三角形。

你甚至可以转置一个完整的矩阵......在你的屏幕截图中,移动到单元格 B13,输入=DIAGONAL(B2,$B$2:$K$11)并向下和向右复制 9x

没有按钮,无需显式启动 Sub ...任何大小的 nxn 矩阵,处理字符串和数字,...

于 2013-10-14T16:04:02.207 回答
1

这是一个使用 VBA 的示例。从一个未填充的表格和一个按钮开始。

屏幕1

然后让按钮运行代码:

Option Explicit

Private Sub symmButton_Click()
    MakeSymmetric Range("B2")
End Sub

Public Sub MakeSymmetric(ByRef r As Range)

    Dim M As Long
    M = CountCols(r)

    Dim vals() As Variant
    vals = r.Resize(M, M).Value2

    Dim i As Long, j As Long
    For i = 2 To M
        For j = 1 To i - 1
            vals(i, j) = vals(j, i)
        Next j
    Next i

    r.Resize(M, M).Value2 = vals
End Sub


Public Function CountCols(ByRef r As Range) As Long
    If IsEmpty(r) Then
        CountCols = 0
    ElseIf IsEmpty(r.Offset(0, 1)) Then
        CountCols = 1
    Else
        CountCols = r.Worksheet.Range(r, r.End(xlToRight)).Columns.Count
    End If
End Function

最后观察结果

在此处输入图像描述

于 2013-10-14T14:12:09.580 回答
1

与肖恩的解决方案类似,我也会使用公式。为了获得转置后的值,请使用以下公式:

=INDEX($B$2:$G$7,COLUMN()-COLUMN($B$2)+1,ROW()-ROW($B$2)+1)

如果您想做更复杂的操作(例如=10-[transposedValue]),我建议您使用命名范围:插入新名称,例如TransposedValue在名称管理器中。提供上述公式,而不是单元格链接。现在您可以在矩阵中写下以下公式:

=10-TransposedValue
于 2013-10-30T15:20:40.990 回答
0

我有这个办法。正如您所说,复制粘贴转置工作在矩形范围内。你的问题是你有一个三角形范围。

你会喜欢这个的......

1)。选择包含上三角矩阵的正方形范围并复制。

2)。在空白处选择一个单元格,然后执行以下两个步骤

  • a.) 选择性粘贴 - 值
  • b.)选择性粘贴 - 值 - 转置 - 跳过空白

你有你的对称矩阵:-)

阿尼尔。

于 2015-02-24T14:08:25.247 回答
0

将 Ja72 的填充代码与 SeanC c 的 Excel 函数代码混合在一起,我想我可以制作一个用动态 Excel 公式正确预填充的通用矩阵模板。如此动态,无需任何复制和粘贴即可重复使用。

Public Sub MakeSymmetric(ByRef r As Range)

    Dim M As Long
    M = 300
    ' Was CountCols(r), but I just limited to 300 columns for now

    Dim vals() As Variant
    vals = r.Resize(M, M).Value2

    Dim i As Long, j As Long
    For i = 2 To M
        For j = 1 To i - 1
            vals(j, i) = "=OFFSET($B$2,COLUMN()-COLUMN($B$2),ROW()-ROW($B$2))"

        Next j
            'Make diagonal down the middle show ---
            vals(j, i) = "---"
    Next i
    vals(1, 1) = "---"

    r.Resize(M, M).Value2 = vals
End Sub

Sub FillSymmetric()
    MakeSymmetric Range("B2")
End Sub

虽然我真的不知道任何VB,所以我还没有完全弄清楚如何填充标题。我也不知道 Stackoverflow,但我会尝试添加图片。 要矩阵化的原始列表

将在西南半部输入的值动态转置到东北半部

于 2017-03-27T07:25:44.890 回答
0

简短的回答:INDIRECT(ADDRESS(COLUMN(D2), ROW(D2)))

说明:您可能还记得我们使用带数字的坐标来表示笛卡尔坐标系中的位置。因此,很容易获得对角对称值,例如只需将 (2, 3) 更改为 (3, 2)。

但是在 Excel 中,如果我们想这样做,我们需要一个 wordaround。因为,地址是由字母和数字的组合标记的,比如说B2。您不能只是更改B22B. 幸运的是,我们仍然可以利用 COW() 和 COLUMN() 的强大功能使用数字来表示一个单元格。

在下图中,C2并且B3是对称的。这显示了如何把 to 的C2B3在此处输入图像描述

于 2017-05-04T15:05:17.643 回答
0

使来自 CW 的公式更通用(类似于 Peter Albert),当您的矩阵不是从以下位置开始时,这将有所帮助,A1例如C10

=INDIRECT(ADDRESS(COLUMN(C11)-COLUMN($C$10)+1,ROW(C11)-ROW($C$10)+1))

因此,减去原始行/列并加 1。

于 2022-02-21T21:18:02.143 回答