问:当我的系统剩余电量充足(办公室为64位)时,为什么内存不足
问:分裂后的数据会导致这种奇怪的行为吗?
问:如果拆分该字符串会导致问题,那么如何清理/恢复它只是为了存储/恢复该字符串的操作?
规格:在系统中赢取8.1 Pro + Office 2013 64位,8GB RAM
这是代码,它只获得单个LARGE(~1~2MB)字符串,并将其拆分为多个单元格,因此每个单元格限制32k字符不会造成伤害:
Public Sub SaveConst(str As String)
Dim i As Long
i = 0
' Clear prior data
Do While LenB(Range("ConstJSON").Offset(0, i)) <> 0
Range("ConstJSON").Offset(0, i) = ""
i = i + 1
Loop
Dim strLen As Long
With Range("ConstJSON")
.Offset(0, 0) = Left$(str, 30000)
i = 1
strLen = Len(str)
Debug.Print strLen
Do While strLen > i * 30000
.Offset(0, i) = Mid$(str, i * 30000 + 1, 30000)
Debug.Print i
i = i + 1
Loop
End With
End Sub
现在Len(str)报告~270k个字符,然后我上升到4次迭代,然后“内存不足”错误开始。
现在这是该地方那个bug的第n次迭代。但我有简化/修改代码,以便它有时工作。对于完全相同的数据集。
更新: 对于Jean代码,我相信它会导致该单元的SAVING部分字符串导致该错误。
.Offset(0, i) = Mid$(str, i * 30000 + 1, 30000)
或者
Range("ConstJSON").Resize(nPieces).Value2 = v
两者都会导致错误。
更新2: 我正在将这个字符串保存到单个单元格而不用大惊小怪。但是现在这个字符串变得太大而不适合,分裂有时会导致错误“Out of the memory”。 示例性字符串:
[...] “” ebiZlecenias “”:[{ “” ID “”: “” 91a75940-6d3e-06f8-bcf7-28ecd49e85f2 “”, “” LP “”:空 “” 名 “”: “” ZLECENIE GŁÓWNE “”, “” date_entered “”: “” 2014年4月15日 8点13分18秒 “” “” DATE_MODIFIED “”: “” 2014年4月15日 8点13分18秒 “” “” modified_user_id “”: “” 2 “”, “” budowa_id “”: “” 8614aab5-29da-FFAC-4865-e8c5913c729c “”, “” rodzaj “”: “” 1" “ ”“ ETAP ”“: ”“ 1 ”“, ”“ data_akceptacji ”“:空 ”“ OPIS ”“:空 ”“ USER_ID ”“:空 ”“ data_bazowa_od ”“:空 ”“ data_bazowa_do” “:空”, “data_rzeczywista_od” “:空”, “data_rzeczywista_do” “:空”, “archiwalny” “:空”, “删除” “:空”, “termin_raportowania” “:空”, “okres_raportowania”“:空值, [...]
答案 0 :(得分:2)
这值得一试:首先将字符串拆分成一个数组,然后立即将整个数组打到表单上。
Const pieceLength As Long = 3000
Dim s As String
Dim i As Long
Dim nPieces As Long
Dim v As Variant
s = ... ' whatever your string is...
nPieces = WorksheetFunction.Ceiling(Len(s) / pieceLength, 1)
ReDim v(1 To nPieces, 1 To 1)
For i = 1 To nPieces
v(i, 1) = Mid(s, (pieceLength * i) + 1, pieceLength)
Next i
Range("ConstJSON").Resize(nPieces).Value2 = v
我没有测试过您的代码,所以不能确切地说出它的错误,但我知道一次一个地写入(或读取)单个单元格是缓慢且昂贵的;通常要更好地向/从数组读取/写入大量的单元格,并操纵数组(而不是单元格)。
答案 1 :(得分:2)
编辑:我相信您的标本字符串的问题是某些子字符串以&#34; - &#34;开头。当发生这种情况时,Excel认为内容是一个公式,这就是导致错误的原因。将单元格预先格式化为文本并不能解决问题,但在每个条目前面加上单引号&#39;,强制输入文本并且不会显示,除非在公式栏中,似乎已更正我的宏中的问题,即使使用上面的标本字符串作为&#34; base&#34;字符串。
EDIT2:似乎正在发生的事情是,如果字符串长度大于8,192个字符(公式中允许的最长字符),并且还启动了令Excel认为它可能的令牌是一个公式(例如: - ,+,=),对单元格的写入将失败并出现内存不足错误即使该单元格被格式化为文本。如果首先插入单引号,则不会发生这种情况。
下面是一些适用于更长字符串的代码。
下面的代码首先创建一个长字符串,在这种情况下,字符串略大于100,000,000个字符,然后将其拆分为连续列。没有错误:
Option Explicit
Sub MakeLongString()
Dim S As String
Const strLEN As Long = 100 * 10 ^ 6
Const strPAT As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
S = strPAT
Do
S = S & S
Loop Until Len(S) > strLEN
Debug.Print Format(Len(S), "#,###")
SplitString (S)
Debug.Print Range("a1").End(xlToRight).Column
End Sub
Sub SplitString(STR)
Dim R As Range
Dim strLEN As Long
Set R = [a1]
Dim I As Long
strLEN = Len(STR)
Do Until I > strLEN
R(1, I / 30000 + 1) = "'" & Mid(STR, I + 1, 30000)
I = I + 30000
Loop
End Sub
我刚刚运行了一个测试,其中写入的范围是一个多单元格区域,目标是由Offset方法设置的,并且它也运行完成而没有错误,填入前四行。
Sub SplitString(STR)
Dim R As Range
Dim strLEN As Long
Set R = [a1:a4]
Dim I As Long
strLEN = Len(STR)
Do Until I > strLEN
R.Offset(, I / 30000) = "'" & Mid(STR, I + 1, 30000)
I = I + 30000
Loop
End Sub